如何使用P / Invoke将MemoryStream数据传递给非托管C ++ DLL

时间:2009-06-28 01:30:11

标签: c# c++ parameter-passing memorystream

我需要您的帮助以下方案:

我正在将一些数据从硬件读入MemoryStream(C#),我需要将这些数据在内存中传递给在非托管C ++中实现的dll(使用指针??)。 读取的数据(流入)非常大(兆字节)。我知道我可以P / Invoke这个dll,但我不确定如何将流数据的指针/引用传递给C ++ API?

我必须承认我很困惑,因为我是C#的新手 - 我需要使用unsafe / fixed,因为数据很大或者这些是无关紧要的,因为MemoryStream对象是由GC管理的吗?一些示例代码/详细描述将非常有用。感谢

非托管API的签名:

BOOL doSomething(void * rawData,int dataLength)

1 个答案:

答案 0 :(得分:13)

如果它只是期望字节,你可以将MemoryStream读入一个字节数组,然后将指针传递给该方法。

您必须声明外部方法:

[DllImport("mylibrary.dll", CharSet = CharSet.Auto)]
public static extern bool doSomething(IntPtr rawData, int dataLength);

然后,将MemoryStream中的字节读入字节数组。分配一个GCHandle

  

分配后,您可以使用GCHandle   防止托管对象   被垃圾收集   非托管客户端时的收集器   拥有唯一的参考。没有这样的   一个句柄,可以收集对象   之前由垃圾收集器   完成其工作代表   非管理客户。

最后,使用AddrOfPinnedObject方法将IntPtr传递给C ++ dll。

private void CallTheMethod(MemoryStream memStream)
{
   byte[] rawData = new byte[memStream.Length];
   memStream.Read(rawData, 0, memStream.Length);

   GCHandle rawDataHandle = GCHandle.Alloc(rawData, GCHandleType.Pinned);
   IntPtr address = handle.AddrOfPinnedObject ();

   doSomething(address, rawData.Length);
   rawDataHandle.Free();
 }