c# - GUID 的 COM SAFEARRAY 从 C++ 返回到 C#

标签 c# c++ com guid safearray

我目前遇到需要将 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/

相关文章:

python - 如何为 COM 构造对象列表?

c# - 如何从第一项之外的 foreach 枚举

c++ - 在另一个函数中使用函数内部声明的 vector

python - Ctypes 从 C++ 捕获异常

c++ - 使用构造函数进行引用初始化

c++ - 无需安装即可使用 SqlServer CE

c++ - 我如何强制客户端调用显式专用模板而不是主模板?

c# - Access c# 数据库 OleDbException

c# - logstash @timestamp 到 .NET 中强类型的 Elasticsearch 映射

c# - C# 的 GCM 或 CCM 实现