【问题标题】:Marshaling a SAFEARRAY of Managed Structures by COM Interop通过 COM Interop 编组托管结构的 SAFEARRAY
【发布时间】:2012-09-14 05:34:54
【问题描述】:

我正在尝试将从 c# 库导出的结构数组传递给 c++ 代码。目标是将结构的 SAFEARRAY 从 c++ 传递到 c#。

我已按照

的指示进行操作

http://limbioliong.wordpress.com/2011/07/16/marshaling-a-safearray-of-managed-structures-by-com-interop-part-2/

但调用 GetRecordInfoFromTypeInfo 时出现此错误

0x80028019 旧格式或无效类型库。

【问题讨论】:

  • 这没有帮助(stackoverflow.com/questions/12503041/…)有什么原因吗?你真的需要一个 SAFEARRAY 吗?它必须是一个结构吗?需要实现dispatch接口吗?
  • 之前的尝试是将结构从 C# 传递到 c++,而现在我正在做相反的事情。 LPArray 编组的问题在于它仅编组数组中的一个元素,并且可变长度数组未绑定到 C# 签名中定义的数组。所以我不得不将 marshall 改为 Safearray。请让我知道以前的方法是否有效。
  • 那么这部分有点令人困惑:“我正在尝试将从 c# 库导出的结构数组传递给 c++ 代码”。我很惊讶 LPArray 只编组一个元素(从非托管到托管)
  • 为方便起见,我使用 c# 代码定义了所有结构。我正在使用 c++ 中的那些结构。在第一种情况下,我从 C++ 获取结构,现在我将结构推入 C#。当我这样做时,我将它编组为 LPArrary 并在 C# 签名中声明为 MyStruct[] mystruct 但只有一个元素被传递。我可以通过设置 sizeconst 属性发送多个元素,但它会被硬编码。将由 c++ 填充的结构传递给 c# 的任何方式。
  • 有什么想法吗?感谢您的帮助。

标签: c# c++ com safearray


【解决方案1】:

如果您不需要调度接口,以下应该可以工作:

void MyMethod([MarshalAs(UnmanagedType.LPArray, SizeParamIndex=1)] MyStruct[] data, long size);

如果您需要使用 SAFEARRAY,我希望以下内容可以正常工作(但我不能 100% 确定,因为我目前没有可用的 Windows 机器):

void MyMethod([MarshalAs(UnmanagedType.SafeArray, SafeArraySubType=VarEnum.VT_USERDEFINED)] MyStruct[] data);

如果您负担得起将您的 struct 更改为 class 的费用,那么这也将起作用,并让您免于 UDT 的麻烦:

void MyMethod([MarshalAs(UnmanagedType.SafeArray, SafeArraySubType=VarEnum.VT_UNKNOWN)] MyStruct[] data);

【讨论】:

  • 如何在 c# 的第一个签名中使用 MyStruct[] 数据的大小
  • 好的,SizeParamIndex 是指定大小的参数的索引。
  • 您将如何编写将安全数组从 c++ 返回到 c# 的方法? c++和c#端的方法签名应该是什么?
【解决方案2】:

结构是否包含字符串?如果是这样,请确保标记它们 [MarshalAs(UnmanagedType.BStr)]。 COM 中有一个限制:结构数组中的字符串必须是 BSTR。 TLBExp 默认为 LPWSTR,然后调用终止。见这里:http://msdn.microsoft.com/en-us/library/z6cfh6e6(v=vs.100).aspx

【讨论】:

    猜你喜欢
    • 2012-05-21
    • 2012-08-03
    • 2012-02-24
    • 2011-03-08
    • 1970-01-01
    • 2015-10-26
    • 2010-10-14
    • 2018-04-27
    • 1970-01-01
    相关资源
    最近更新 更多