Transferring data from unmanaged code (C) to managed code (C #)

I have an application written in C# and using a DLL written in C After some delegate (function pointer), I managed to call the C function. This function is expected to do a lot of processing on some data, and then return the processed binary data back to C# along with the size of the data.

The prototype of the C# managed function is:

private unsafe delegate void MyCallback (IntPtr cs_buf, Int32 cs_size);

And I call this from my C code as:

 void* c_buf = NULL; int c_size = 0; .... some processing here to fill buf and size...... MyCallback (c_buf, c_size); 

In C# managed code, I need to call a function from MyCallback that has a prototype:

void foo (byte[] cs_buf, int cs_size)

Now there is no problem with the cs_size value, but what is the correct way to use / transfer the binary buffer from C code to C # code so that it can be used as byte[] in C # code.

If what I am doing is the correct way, what should be the recommended way to convert the received IntPtr cs_buf to byte[] ?

Thanks Vikram

+4
source share
2 answers

You must use Marshal.Copy

Marshal.Copy Method (IntPtr, Byte[], Int32, Int32)

Copies data from an unmanaged memory pointer to a managed 8-bit unsigned integer array.

Assuming cs_size is the size in bytes:

 var array = new byte[cs_size]; Marshal.Copy(pointer, array, 0, cs_size); foo(array, cs_size); 

By the way, in this case foo() does not need to take the cs_size parameter, since it can use the .Length property for the array.


Also with this, since C # code copies the array, you could free() use the buffer from C code right after calling the callback.

Otherwise, you will need to either export the mylib_free() method from C, or use a well-known memory allocator (NOT malloc ), such as LocalAlloc (From C) and Marshal.FreeHGlobal (from C #) under Windows.

+2
source

This is what Microsoft has done C ++ / CLI for (also known as Managed C ++). You can write a function like this:

 void call_foo(array<Byte>^ bytes) { pin_ptr<Byte> ptrBuffer = &bytes[bytes->GetLowerBound(0)]; foo(ptrBuffer, bytes->Length); } 

This will take a C # byte array, write its memory, and then pass it as an array of C styles in bytes to foo with its length. There is no need to clean or empty everything. The attached pointer will be automatically disabled when it disappears from the scope at the end of call_foo. Clean and simple.

+4
source

All Articles