开发者

C# P/Invoke [DllImport] - array memory management

I'm passing a byte[] to a function accepting an unsigned char*

One way I can do this is to pass an IntPtr, and allocate/deallocate memory in managed code as follows:

  • in C++ DLL

    extern "C" 
    {
        __declspec(dll开发者_如何学Cexport) void __stdcall Foo(int length, unsigned char** message);
    }
    
  • in 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);
    

I can also do this:

  • in C++ DLL

    extern "C" 
    {
        __declspec(dllexport) void __stdcall Foo(int length, unsigned char* message);
    }
    
  • in 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);
    

Both implemntations work well, but in my second example, how is the memory (for the unsigned char* message) managed. I'm guessing that memory is allocated when the call to Foo is made, and deallocated when it returns (so it behaves much like the first example) - is this correct?

Thanks


There is no management done in the second case. The GC does not count references done from unmanaged code. This is fine when the external function does not work with threads or uses the reference at a later function call.
There is a similar issue when you are working with delegates/function pointers and unmanaged code, where it can happen to you that the delegate gets dealloacted at a random point. This MSDN article is great to explain you all the details.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜