3

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(dllexport) 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

1
  • I can't understand why you would pass ref ip in the first example. You can't possibly be changing the value of ip. In the second example, unsigned char message[] reads much better. Finally, if you are passing IP addresses around, a struct would be the way to go—no need for a length parameter. Commented Jul 11, 2011 at 18:47

1 Answer 1

2

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.

Sign up to request clarification or add additional context in comments.

3 Comments

I understand that the GC is not involed (maybe I shouldn't have used the term 'manage'), but something must allocate and copy the data onto the unmanaged heap - after all, I am able to access the array for the duration of Foo. What does this?
The allocation is just part of the CLR. Have a look at the article, it explains the details well, e.g. when is memory pinned and when it is copied.
Thanks - I missed the link to the MSDN articale in your previous post. After running some tests I found the second implemntation to be much faster, so I'm going to stick with that.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.