C ++ Interop:在UDT中嵌入数组

时间:2013-06-07 23:45:37

标签: com interop visual-studio-2005

我的应用程序涉及托管(C#)和非托管(C ++)代码之间的大量通信。我们使用的是Visual Studio 2005(!),我们使用tlbimp自动生成的互操作程序集。

我们有很好的运气来回传递简单的结构作为函数参数。因为我们的对象非常简单,我们可以使用IRecordInfo接口将它们打包到SAFEARRAY中。将这些数组作为参数传递给COM方法似乎可以正常工作。

我们希望能够在我们的UDT中嵌入可变长度数组,但这很糟糕。我不认为我能找到一份文件显示某人是如何完成这项工作的。我也没有找到说无法完成的文档。

1)天真的方法:只需在托管代码中声明一个safearray:

struct MyUdt {
  int member1;
  BSTR member2;
  SAFEARRAY *m3;
};

C ++编译器对此感到满意,但生成的IDL使tblimp.exe感到困惑。它报告它无法转换成员m3的签名,以及成员tagSAFEARRAY.rgsabound的签名。这些只是警告,但它们是有意义的,生成的程序集不可用。

奇怪的是,使用LPSAFEARRAY会以不同的方式失败,但出于同样的原因,tblimp无法处理它。

2)Trickier:将其打包成一个变体:

struct MyUdt {
  int member1;
  BSTR member2;
  VARIANT m3;
};

我们有构建UDT安全阵列的代码,它从来没有给我们带来任何麻烦。它基本上是从MSDN复制的。使用该代码创建一个safearray,然后:

pVal->m3.vt = VT_SAFEARRAY | VT_RECORD;
pval->parray = p;

以奇怪的方式失败。它总是打破,一些变化产生一个OutOFMemoryException ......奇怪,其他变化以不同的方式失败。 (我不确定这里是否需要pRecInfo指针,但它的失败方式是相同的,无论是否存在。)

谷歌的搜索空间受到了严重的污染,我不会回答问题:

  • 如何从非托管代码传递UDT /结构。
  • 你如何通过结构的SAFEARRAY? (我们做得很好。)
  • 如何使用p / invoke或客户编组来传递UDT。

许多答案描述了如何从管理方面定义事物,而不是非管理方面。

然后有几个Microsoft KB在早期版本的.NET中描述了VT_RECORD的问题。我不认为这些是密切相关的 - VT_RECORD类型适用于VARIANT和SAFEARRAY。 (但也许不是UDT编组......)

如果这不起作用,至少知道原因会很好。

  • 标记

0 个答案:

没有答案