9

在以下情况下,我需要您的帮助:

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

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

非托管 API 的签名:

BOOL doSomething(void * rawData, int dataLength)
4

1 回答 1

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);
   try
   {
     IntPtr address = rawDataHandle.AddrOfPinnedObject ();

     doSomething(address, rawData.Length);
   }
   finally
   {
     if (rawDataHandle.IsAllocated)
       rawDataHandle.Free();
   }
 }
于 2009-06-28T02:15:02.590 回答