从进程C ++ COM到C#获取字节数组

时间:2009-11-13 15:43:02

标签: c# com interop clr

从COM服务器到C#获取大块内存(即void *)的最佳方法是什么?

我们一直在使用IStream(使用CreateStreamOnHGlobal)并将其传回去,这有效。但是,当我们在使用x32 C ++ COM的x64 CLR上尝试此操作时,它会爆炸。

COM必须是x32,因为它使用外部32位DLL。 C#可能被迫运行32位,但挑战是将其保持为x64。

2 个答案:

答案 0 :(得分:1)

回答我自己的问题。

当您从自己的COM服务器返回IStream时,.NET互操作DLL会将IStream放入其接口。例如,假设类型库是MyComServer,那么interop将包含一个类MyComServer.Interop.IStream。

这个IStream类具有RemoteRead,RemoteWrite等函数。这些函数将ref字节作为第一个参数。使用这些在32位到32位上工作得很好,但是这个参考可能会变成一个指针,所以在64到32之间就出现了问题。

解决方案是使用“as”(或者只是强制转换)将MyComServer.Interop.IStream转换为System.Runtime.InteropServices.ComTypes.IStream。然后,这将为返回大小采用更熟悉的byte [],int count和IntPtr。

IntPtr很烦人,因为它可能是一个out int,但我用过(手动输入这个,所以没有编译器检查..)

byte[] buffer = new byte[100];
IntPtr ptr = Marshall.AllocHGlobal( sizeof(int) );
stream.Read( buffer, 100, ptr );

答案 1 :(得分:0)

如果您有.NET 3.5,请查看System.IO.Pipes - 创建一个众所周知的管道名称,并使用Win32 named pipes APIs从非托管代码中喷出它。