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.