pinvoke: How to free a malloc'd string?
在C dll中,我具有这样的功能:
1 2 3 4 5 6 7 8 | char* GetSomeText(char* szInputText) { char* ptrReturnValue = (char*) malloc(strlen(szInputText) * 1000); // Actually done after parsemarkup with the proper length init_parser(); // Allocates an internal processing buffer for ParseMarkup result, which I need to copy sprintf(ptrReturnValue,"%s", ParseMarkup(szInputText) ); terminate_parser(); // Frees the internal processing buffer return ptrReturnValue; } |
我想使用P / invoke从C#调用它。
1 2 | [DllImport("MyDll.dll")] private static extern string GetSomeText(string strInput); |
如何正确释放分配的内存?
我正在编写针对Windows和Linux的跨平台代码。
编辑:
像这样
1 2 3 4 5 6 7 8 9 | [DllImport("MyDll.dll")] private static extern System.IntPtr GetSomeText(string strInput); [DllImport("MyDll.dll")] private static extern void FreePointer(System.IntPtr ptrInput); IntPtr ptr = GetSomeText("SomeText"); string result = Marshal.PtrToStringAuto(ptr); FreePointer(ptr); |
您应该将返回的字符串编组为
请参见此几乎(但不是完全)重复的问题PInvoke for返回char *的C函数。
理想情况下,当您希望释放字符串时,您的C dll还应公开一个
如果返回使用本机malloc分配的.net内存,则还必须导出解除分配器。我不认为这是理想的操作,而是希望将文本导出为
唯一的麻烦是
C
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | #include <comutil.h> BSTR ANSItoBSTR(const char* input) { BSTR result = NULL; int lenA = lstrlenA(input); int lenW = ::MultiByteToWideChar(CP_ACP, 0, input, lenA, NULL, 0); if (lenW > 0) { result = ::SysAllocStringLen(0, lenW); ::MultiByteToWideChar(CP_ACP, 0, input, lenA, result, lenW); } return result; } BSTR GetSomeText(char* szInputText) { return ANSItoBSTR(szInputText); } |
C#
1 2 3 | [DllImport("MyDll.dll", CallingConvention=CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.BStr)] private static extern string GetSomeText(string strInput); |
添加另一个调用