简体   繁体   中英

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

I have an application that is written in C# and uses a DLL written in C . Through some delegate (function pointer), I have managed to invoke a 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# code along with size of data.

The prototype for managed c# function is:

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

And I am calling 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 the managed C# code, I need to call a function from MyCallback that has the 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/pass the binary buffer from C code to C# code so that it can be used as a byte[] in C# code.

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

Thanks, Vikram

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

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

This would take a C# array of bytes, pin its memory, and then pass it as a C style array of bytes to foo, with its length. There is no need for cleanup or to free anything. The pinned pointer will get auto-unpinned when it goes out of scope at the end of call_foo. Clean and simple.

You should 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 that 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 int this case foo() don't need to take a cs_size parameter as it could use the .Length property of the array instead.


Also with this, as the C# code copy the array, you could free() the buffer from the C code just after calling the callback.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM