c# P/Invoke [DllImport] -数组内存管理
本文关键字:数组 内存 管理 DllImport Invoke | 更新日期: 2023-09-27 18:01:49
我将一个byte[]传递给一个接受unsigned char*的函数
我可以这样做的一种方法是传递一个IntPtr,并在托管代码中分配/释放内存,如下所示:- c++ DLL中的
extern "C" { __declspec(dllexport) void __stdcall Foo(int length, unsigned char** message); }
用c# [DllImport(@"MyDll.dll"] public static extern void Foo(int length, ref IntPtr msg); byte[] msg = new byte[] {0,1,2,3}; IntPtr ip = Marshal.AllocHGlobal(msg.Length); Marshal.Copy(msg, 0, ip, msg.Length); UnmanagedCode.Foo(msg.Length, ref ip); Marshal.FreeHGlobal(ip);
我也可以这样做:
- c++ DLL中的
extern "C" { __declspec(dllexport) void __stdcall Foo(int length, unsigned char* message); }
用c# [DllImport(@"MyDll.dll"] public static extern void Foo(int length, byte[] msg); byte[] msg = new byte[] {0,1,2,3}; UnmanagedCode.Foo(msg.Length, msg);
两种实现都工作得很好,但在我的第二个例子中,如何管理内存(用于unsigned char*消息)。我猜内存是在调用Foo时分配的,当它返回时释放(所以它的行为很像第一个例子)-这是正确的吗?
谢谢
在第二种情况下没有进行管理。GC不计算来自非托管代码的引用。当外部函数不与线程一起工作或在以后的函数调用中使用引用时,这是可以的。
有一个类似的问题,当你与委托/函数指针和非托管代码工作,它可能发生在你的委托在一个随机点被释放。这篇MSDN文章很好地解释了所有的细节。