我有一个用C#编写的应用程序,它使用用C编写的dll。
通过一些委托(函数指针),我成功地调用了一个C函数。这个函数需要对一些数据进行大量处理,然后将处理后的二进制数据返回到C#代码以及数据的大小。
managedc#函数的原型是:
private unsafe delegate void MyCallback (IntPtr cs_buf, Int32 cs_size);
我的C code称之为:

void* c_buf = NULL;
int c_size = 0;

.... some processing here to fill buf and size......

MyCallback (c_buf, c_size);

在托管C#代码中,我需要从MyCallback调用一个具有原型的函数:
void foo (byte[] cs_buf, int cs_size)
现在cs_size值没有问题,但是使用/将二进制缓冲区从c代码传递到c代码的正确方法是什么,以便它可以用作c代码中的byte[]
如果我所做的是正确的方法,那么建议将接收到的IntPtr cs_buf转换为byte[]的方法是什么?
谢谢,
维克拉姆

最佳答案

您应该使用Marshal.Copy
Marshal.Copy Method (IntPtr, Byte[], Int32, Int32)
将数据从非托管内存指针复制到托管8位
无符号整数数组。
假设cs_size是字节大小:

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

顺便说一下,这个casefoo()不需要使用cs_size参数,因为它可以使用数组的.Length属性。
同样,当C代码复制数组时,您可以在调用回调之后从C代码中free()缓冲区。
否则,您需要从C导出mylib_free()方法,或者在Windows下使用已知的内存分配器(不是malloc),如LocalAlloc(从C)和Marshal.FreeHGlobal(从C)。

07-28 02:44
查看更多