我有许多需要从 WF4 活动访问的 COM 库,因此我曾经tlbimp为它们生成托管包装器。这很好用,但在某些情况下,有一个 COM 方法需要一个 Variants 数组作为其参数之一,并且该数组的元素之一是来自另一个 DLL 的 COM 类的实例,我可以'即使我有对表示同一对象的托管包装器的引用,也看不到如何获得引用。
例如,假设我有两个名为ABCand的 COM 库DEF,为此我创建了名为ABCManagedand DEFManagedusing的托管包装器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对象编组为非托管类型。DEFCallFunction()
在这里也不能选择直接使用 P/Invoke;我当然可以编写代码,但其中一项要求是 WF4 活动的用户能够访问DEFManaged对象的属性和方法,因此它们需要是托管对象。