从 type-lib 使用 tlbimp.exe 重新生成 interop.dll 时,打开数组声明丢失

Open array declaration lost when regenerating interop.dll with tlbimp.exe from type-lib

我需要从类型库中重新生成 interop.dll。因此我开火了

TlbImp.exe" foo.tlb /out:interop.dll

但是对比原来的interop.dll,我用对象浏览器发现了(见下文)

void SetNodeArr(int Size, FOO_NODE[] pArray)       // original interop.dll

SetNodeArr 的方法参数的开放数组丢失:

void SetNodeArr(int Size, ref FOO_NODE pArray)     // regenrated interop.dll

我尝试了 TlbImp.exe 的一些选项,但没有成功。

Q 我需要做哪些调整才能将参数 pArray 声明为开放数组而不是简单引用?

这是一个很正常的事故。您可以通过 Visual Studio 命令提示符中的 运行 OleView.exe 查看潜在问题。使用 File + View Typelib 和 select .tlb。您应该会看到如下内容:

   void SetNodeArr(int Size, FOO_NODE* pArray); 

指针有问题,有歧义。这可能意味着参数是一个数组,也可能意味着它是一个通过引用传递的结构。

对于设计用于 C 或 C++ 程序的 COM 服务器,您会看到这样的声明。当数组作为参数传递时,数组衰减为指向第一个元素的指针的一种语言。

这不适用于将数组视为对象的语言,例如 .NET 语言。支持多种不同语言的友好 COM 服务器会将此参数声明为 SAFEARRAY。现在参数的类型是什么是明确的,它总是一个数组。也不需要 Size 参数,安全数组知道自己的大小。它是一个对象。

所以 Tlbimp.exe 没有机会去猜测正确的翻译,它总是选择 struct-passed-by-reference,这是最安全的选择。因此 ref FOO_NODE。当您受困于 COM 服务器的实现方式时,您无法做任何事情来让它变得更明智。

可以修复互操作库,MSDN library 中描述了该过程。使用 ildasm.exe 反编译程序集,编辑 IL 以修复声明(首先使用示例 C# 代码尝试它以查看它应该是什么样子),使用 ilasm.exe[=13 将 humpty-dumpty 再次组合在一起=]