开发者

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

开发者 https://www.devze.com 2023-03-19 04:35 出处:网络
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:

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

精彩评论

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

关注公众号