如何从 C# 将双指针传递给 COM 并在 COM 中初始化它

Posted

技术标签:

【中文标题】如何从 C# 将双指针传递给 COM 并在 COM 中初始化它【英文标题】:How to pass double pointer to COM from C# and initliaze it inside COM 【发布时间】:2013-10-31 16:06:49 【问题描述】:

我创建了一个采用双指针 (BYTE**) 的 COM 方法。在 COM 内部,我正在分配内存并对其进行初始化。

签名是;

HRESULT Canny([in] BSTR szLogoPath, [out] BYTE** pBuffer, [out] USHORT* iBufLen);

问题是当我从 C# 项目调用它时 COM 崩溃,而当我从 WIN32 项目调用它时它工作正常。

此外,在 C# 项目中,上述方法显示为; (BYTE** 显示为 IntPtr)

public virtual void Canny(string szLogoPath,IntPtr pBuffer, out ushort iBufLen);

我的 C# 代码是

LogoFinderClass libCOM = new LogoFinderClass();
unsafe  
    byte* buf = null;
    IntPtr interopPtr = new IntPtr(&buf); 
    libCOM.Canny(@"..\Logo.bmp", interopPtr, out bufLen);

在 C++ 中,我将内存分配为;

::Canny(BSTR szLogoPath, BYTE** pBuffer, USHORT* iBufLen) 
    *pBuffer = new BYTE[1024]; 
    .. 

从 C# 调用时,COM 在分配内存时崩溃。

【问题讨论】:

在 COM 互操作中使用 new 运算符总是错误的。客户端代码没有希望调用正确的 delete 运算符,需要 CoTaskMemAlloc。如果它快速崩溃,那么您很可能会破坏堆。对于像 Canny 这样的图像处理操作来说,1024 字节听起来太低了。 谢谢@HansPassant,我现在正在使用 CoTaskMemAlloc () 并且工作正常,但是 Marshal.Copy(..) 没有复制我在 COM 中分配的字节数,就像我正在分配8000 字节,但它正在复制大约 5000 字节,我认为 IntPtr 在某处损坏。 是的 1024 是精明操作的两个低点,我刚才提到它是虚拟值 Passing byte array between C++ and C# ByRef raises AccessViolationException的可能重复 【参考方案1】:

这里不需要unsafe。您确实需要在 C# 结束时更改函数的声明。缓冲区参数需要声明为:

ref IntPtr pBuffer

然后,调用该函数后,使用Marshal.Copy 读出缓冲区的内容。

我不是从 C# 消费 COM 的出口,但第一个参数不应该有[MarshalAs(UnmanagedType.BStr)]吗?

另外,如果您使用CoTaskMemAlloc 而不是new,您可以让调用者释放缓冲区,而不必导出释放器。我相信您确实导出了释放器?

【讨论】:

感谢@David 的回复。请您告诉我如何在 C# 端编辑函数声明,因为解决方案资源管理器中引用过滤器下的 lib (COM) 没有公开任何属性来编辑其签名。 @SKAR 正如我所说,我不是 C# 的 COM 专家。所以,我不知道VS中的细节。对不起。但肯定有 C# 源代码声明接口的地方? 感谢@David,使用 CoTaskMemAlloc(..) 分配内存时 COM 没有崩溃,但 Marshal.Copy(..) 没有复制我在 COM 中分配的字节数,就像我一样我正在分配 8000 字节,但它正在复制大约 5000 字节,我认为 IntPtr 在某处损坏。但是从 WIN32 调用时它再次工作正常:( @SKAR 使用new[] 没有问题。这不会导致崩溃。它只是强制你导出一个释放器。至于您的其余评论,听起来您的代码中某处存在错误。 谢谢@David,你能举个例子吗?

以上是关于如何从 C# 将双指针传递给 COM 并在 COM 中初始化它的主要内容,如果未能解决你的问题,请参考以下文章

如何通过 COM 接口调用 C# 方法传递函数指针

如何将数据从非托管应用程序传递到 C# COM DLL

如何将双引号中的路径传递给sql文件

如何将 COM 对象的 C# 引用传递给 C++ DLL

数组应该如何从 C# 传递给 Javascript 函数?

如何将指向 C# 结构的指针传递给 C 中的方法