我目前遇到需要将 SAFEARRAY(GUID) 作为返回值从 C++ 传递到 C# 的问题。
目前 C# 端正在使用从 Tlbimp.exe(类型库导入程序)生成的 Interop dll。
IDL 是:
HRESULT GetGuids(
[out]SAFEARRAY(GUID)* guids);
我也试过 [out, retval]
函数签名是:
HRESULT
WINAPI
MyClass::GetGuids(SAFEARRAY** guids)
如果我使用 SafeArrayCreate()
或 SafeArrayCreateVector()
:
SAFEARRAY* psa
psa = SafeArrayCreate(VT_CLSID, 1, rgsabound);
我得到一个 NULL SAFEARRAY
指针,它应该指示 E_OUTOFMEMORY
这是不正确的。
我确实发现 VT_CLSID
仅适用于 Ole 属性集,而不适用于 SAFEARRAY:
http://poi.apache.org/apidocs/org/apache/poi/hpsf/Variant.html它表明CLSID是
我还尝试了另一种构建安全数组的方法:
SafeArrayAllocDescriptor()
和 SafeArrayAllocData()
。
hResult = SafeArrayAllocDescriptor(1, guids)
hResult = SafeArrayAllocData(*guids);
这让我可以创建数组,但是当使用 SafeArrayPutElement()
填充它时,我得到的 HRESULT 为 0x80070057(参数不正确)。这可能是因为它也采用了 VT_CLSID
参数
我可以用 SafeArrayAccessData()
手动填充它
GUID* pData = NULL;
hResult = SafeArrayAccessData(*guids, (void**)&pData);
但是我从 C# 端得到一个错误: “该值不在预期范围内”
我不确定如何通过 retval 或 out 参数实现将 SAFEARRAY(GUID) 返回到 C# 所需的功能。
它看起来应该很简单 - IDL 中的许多区域我已经在没有任何 UDT 或编码的情况下传递了 GUID。一切正常,直到我需要在 SAFEARRAY 中传递它们。
感谢任何帮助, 提前致谢
最佳答案
您完全正确 - 问题是 VT_CLSID 不允许在 VARIANT 或 SAFEARRAY 中使用。归结为 GUID 不是自动化兼容类型。
我经常需要做与您正在尝试的相同的事情。解决该问题的最简单方法是将 GUID 转换为字符串,然后传递 SAFEARRAY(VT_BSTR)。进行这种转换有点违背常理,但我想您可以认为无论如何都在进行编码,并且这种转换是一种编码。
关于c# - GUID 的 COM SAFEARRAY 从 C++ 返回到 C#,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6866464/