更新时间:2023-02-15 21:06:31
一个可能的模式是:
[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
分配的内存。
Note that you'll need a freeMemory
method to free the memory allocated by doJob
.
有其他可能的模式,例如基于 BSTR
和 SysAllocString
更易于实现C#-side (但较难实现的C面)
There are other possible patterns, for example based on BSTR
and SysAllocString
that are easier to implement C#-side (but more difficult to implement C-side)
模式,使用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# - 侧:
C#-side:
[DllImport("containsdojob.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern Int32 doJob([MarshalAs(UnmanagedType.BStr)] out string buffer);
string str;
doJob(out str);
该内存由CLR自动处理(释放)。
The memory is automatically handled (freed) by the CLR.
如果您使用Visual C ++,你甚至可以
If you are using Visual C++ you can even
char *str = "Foo"; // your string
_bstr_t bstrt(str);
BSTR bstr = bstrt.Detach();
// bstr is the returned string
或C端,你可以用它可以释放C# - 侧两个分配器之一:的 LocalAlloc 或 CoTaskMemAlloc :
Or C-side you could use one of the two allocators that can be freed C#-side: LocalAlloc or 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
然后,可以使用第一个例子,但不是叫
Then you use the first example, but instead of calling
freeMemory(buffer);
您拨打:
Marshal.FreeHGlobal(buffer); // for LocalAlloc
或
Marshal.FreeCoTaskMem(buffer); // for CoTaskMemAlloc