简体   繁体   English

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

[英]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 .我有一个用C C# Through some delegate (function pointer), I have managed to invoke a C function.通过一些委托(函数指针),我设法调用了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.这个 function 预计会对一些数据进行大量处理,然后将处理后的二进制数据连同数据大小一起返回给C#代码。

The prototype for managed c# function is:托管c# function 的原型是:

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

And I am calling this from my C code as:我从我的C code中调用它:

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:在托管C#代码中,我需要从具有原型的MyCallback调用 function:

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.现在cs_size值没有问题,但是使用/传递二进制缓冲区从 C 代码到 C# 代码以便它可以用作 ZD7EFA19FBE74D3972FD5ADB74 代码中的byte[]的正确方法是什么。

If what I am doing is the correct way, what should be the recommended way of converting the received IntPtr cs_buf to byte[] ?如果我正在做的是正确的方法,那么将收到的IntPtr cs_buf转换为byte[]的推荐方法应该是什么?

Thanks, Vikram谢谢,维克拉姆

This is what Microsoft made C++/CLI for (also known as Managed C++).这就是微软为(也称为托管 C++)制作的 C++/CLI。 You could write a function like this:你可以这样写一个 function :

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.这将需要一个 C# 字节数组,固定其 memory,然后将其作为 C 样式的字节数组传递给 foo,其长度。 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.固定指针在 call_foo 结束时离开 scope 时将自动取消固定。 Clean and simple.干净简单。

You should use Marshal.Copy你应该使用Marshal.Copy

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

Copies data from an unmanaged memory pointer to a managed 8-bit unsigned integer array.将数据从非托管 memory 指针复制到托管 8 位无符号 integer 数组。

Assuming that cs_size is the size in bytes:假设cs_size是以字节为单位的大小:

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.顺便说一句,在这种情况下foo()不需要采用cs_size参数,因为它可以使用数组的.Length属性。


Also with this, as the C# code copy the array, you could free() the buffer from the C code just after calling the callback.此外,由于 C# 代码复制数组,您可以在调用回调后从 C 代码中free()缓冲区。

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. 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.

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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