C# Free IntPtr from C malloc
-
02-07-2021 - |
题
I have an unmanaged DLL on C with func:
char* My_Func(char* data, int input_length, int output_length);
In this func i have
result = (char*)malloc(output_lenght);
strcpy(result,test_char);
return(result);
In C# i import it
[DllImport(@"libsmev.DLL", CharSet = CharSet.Ansi)]
public static extern IntPtr My_Func([MarshalAs(UnmanagedType.LPStr)]string data, int input_length, out int output_length);
And call it
IntPtr result = My_Func (n1, n1.Lenght,n2);
How to free char* or IntPtr?
Marshal.FreeHGlobal(IntPtr) and Marshal.FreeCoTaskMem(IntPtr) doesn`t work.
解决方案
In C, something like this:
void Free_Obj(char* obj) {
free(obj);
}
In C#, something like this:
[DllImport("libsmev.DLL")]
public static extern void Free_Obj(IntPtr obj);
And call it:
IntPtr result = My_Func (n1, n1.Lenght,n2);
Free_Obj(result);
其他提示
You need to export a function that can free the pointer using free
. As you have noticed Marshal.FreeHGlobal
and Marshal.FreeCoTaskMem
doesn't work because these functions expect pointer that have allocated using a different allocation function.
If you create an API that allocates memory and returns a pointer to this memory you have to also add a function in the API to free the memory. Otherwise your API will not be available outside the library that was used to allocate the memory (in this case the C standard library).
Instread of creating a custom free function in your DLL, you could also use CoTaskMemAlloc instead of malloc
to allocate the memory.
You can then use Marshal.FreeCoTaskMem
to free it.