其中一种可能的模式是:
[DllImport("containsdojob.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern Int32 doJob(out IntPtr buffer);
[DllImport("containsdojob.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void freeMemory(IntPtr buffer);
和
IntPtr buffer = IntPtr.Zero;
string str = null;
try
{
doJob(out buffer);
if (buffer != IntPtr.Zero)
{
str = Marshal.PtrToStringAnsi(buffer);
}
}
finally
{
if (buffer != IntPtr.Zero)
{
freeMemory(buffer);
}
}
请注意,您需要一个freeMemory 方法来释放doJob 分配的内存。
还有其他可能的模式,例如基于BSTR 和SysAllocString,更容易实现 C# 端(但更难实现 C 端)
使用 BSTR 的“模式”:
C端:
char *str = "Foo"; // your string
int len = strlen(str);
int wslen = MultiByteToWideChar(CP_ACP, 0, str, len, 0, 0);
BSTR bstr = SysAllocStringLen(NULL, wslen);
MultiByteToWideChar(CP_ACP, 0, str, len, bstr, wslen);
// bstr is the returned string
C#端:
[DllImport("containsdojob.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern Int32 doJob([MarshalAs(UnmanagedType.BStr)] out string buffer);
string str;
doJob(out str);
内存由 CLR 自动处理(释放)。
如果你使用 Visual C++,你甚至可以
char *str = "Foo"; // your string
_bstr_t bstrt(str);
BSTR bstr = bstrt.Detach();
// bstr is the returned string
或者 C 端,您可以使用可以在 C# 端释放的两个分配器之一:LocalAlloc 或 CoTaskMemAlloc:
char *str = "Foo"; // your string
char *buf = (char*)LocalAlloc(LMEM_FIXED, strlen(str) + 1);
// or char *buf = (char*)CoTaskMemAlloc(strlen(str) + 1);
strcpy(buf, str);
// buf is the returned string
然后你使用第一个例子,而不是调用
freeMemory(buffer);
你打电话:
Marshal.FreeHGlobal(buffer); // for LocalAlloc
或
Marshal.FreeCoTaskMem(buffer); // for CoTaskMemAlloc