【发布时间】: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 是精明操作的两个低点,我刚才提到它是虚拟值