我有许多需要从 WF4 活动访问的 COM 库,因此我曾经tlbimp
为它们生成托管包装器。这很好用,但在某些情况下,有一个 COM 方法需要一个 Variants 数组作为其参数之一,并且该数组的元素之一是来自另一个 DLL 的 COM 类的实例,我可以'即使我有对表示同一对象的托管包装器的引用,也看不到如何获得引用。
例如,假设我有两个名为ABC
and的 COM 库DEF
,为此我创建了名为ABCManaged
and DEFManaged
using的托管包装器tlbimp
。假设DEF
有一个具有以下签名的方法(请原谅 VB 风格的签名,这就是它在文档中的方式):
CallFunction (parmArray() as Variant) as Long
这表示DEFManaged
如下:
int CallFunction(ref object parmArray)
到现在为止还挺好。现在,作为参数的变量数组的元素是CallFunction()
不同类型的,所以在我的例子中,第一个元素是 adouble
而第二个元素是ABC
. 以下是我如何构建我的数组以传递给我的 managed CallFunction()
:
// obtain our managed ABC from the workflow context
ABCManaged abc = context.GetValue(this.InputABC);
object[] parameters = new object[2];
parameters[0] = new double();
parameters[1] = abc;
DEFManaged def = new DEFManaged();
def.CallFunction(parameters);
这编译得很好,但不起作用 - 调用CallFunction()
抛出这个异常:
System.ArgumentException: Value does not fall within the expected range.
我的猜测是,def
它没有正确编组到底层的非托管DEF
类型,可能是因为签名只是有一个数组object
,并且确定数组元素的真实类型的逻辑在 COM 方法的实现中的某个地方CallFunction()
。在将对象粘贴到数组中以传递给我的 managed 之前,我无法弄清楚如何手动将我的def
对象编组为非托管类型。DEF
CallFunction()
在这里也不能选择直接使用 P/Invoke;我当然可以编写代码,但其中一项要求是 WF4 活动的用户能够访问DEFManaged
对象的属性和方法,因此它们需要是托管对象。