将数据从非托管代码 (C) 传递到托管代码 (C#)

Vik*_*exe 5 c c#

我有一个C#C. 通过一些委托(函数指针),我成功地调用了一个C函数。该函数预计会对某些数据进行大量处理,然后将处理后的二进制数据C#以及数据大小返回给代码。

托管函数的原型c#是:

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

我从我的C codeas 中调用这个:

void* c_buf = NULL;
int c_size = 0;

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

MyCallback (c_buf, c_size);
Run Code Online (Sandbox Code Playgroud)

在托管代码中,我需要调用具有原型的C#函数:MyCallback

void foo (byte[] cs_buf, int cs_size)

现在该值没有问题cs_size,但是使用/将二进制缓冲区从 C 代码传递到 C# 代码以使其可以用作byte[]C# 代码中的 a 的正确方法是什么。

如果我所做的是正确的方法,那么将收到的转换为的推荐方法应该是IntPtr cs_buf什么byte[]

谢谢,维克拉姆

Jul*_*lia 3

你应该使用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);
Run Code Online (Sandbox Code Playgroud)

顺便说一句, int 这种情况foo()不需要接受cs_size参数,因为它可以使用.Length数组的属性。


此外,当 C# 代码复制数组时,您可以free()在调用回调后立即从 C 代码中获取缓冲区。

否则,您将需要mylib_free()从 C 导出方法或使用已知的内存分配器(NOT malloc),例如Windows 下的LocalAlloc(From C) 和Marshal.FreeHGlobal(From C#)。