如何调用(从COM对象)返回VBScript对象数组的方法

时间:2014-08-06 09:26:40

标签: vba vbscript com interop

我有一个COM对象' Foo'它定义了一个返回Bar数组的函数:

public Bar[] Bars()
{
    return bars;
}

这是在COM中注册的DLL。

我可以这样从VBA调用它:

Dim aBars() As Bar
aBars = oFoo.Bars()

Dim oBar As Bar
Set oBar = aBars(0)

但是,我需要从VBScript调用相同的函数,它没有早期绑定支持,当我尝试这个时,它失败了:

Dim aBars
aBars = oFoo.Bars()

Dim oBar
Set oBar = aBars(0) ' fails with 'Type Mismatch'

如果我检查了aBars'的类型,那就是' Unknown()',我想这就是为什么它不知道如何处理它。

我可以做些什么来完成这项工作?

2 个答案:

答案 0 :(得分:1)

Bar类或接口上的属性有问题,它没有像脚本语言那样实现IDispatch。只有IUnknown,VBA可以处理但VBScript无法处理的东西。根据脚本运行时的需要,IDispatch需要支持后期绑定。

我根本看不到Bar,所以不得不猜测。如果它是实现接口的接口或类,那么您需要[InterfaceType(ComInterfaceType.InterfaceIsDual)]来获得对早期和晚期绑定的支持。或ComInterfaceType.InterfaceIsIDispatch用于后期绑定。

如果是课程,则需要[ClassInterface(ClassInterfaceType.AutoDual)]才能获得早期和晚期的支持。或ClassInterfaceType.AutoDispatch为迟到。

Boilerplate留下的麻烦是:

[ComVisible(true)]
[InterfaceType(ComInterfaceType.InterfaceIsDual)]
public interface IBar {
    // etc...
}

[ComVisible(true)]
[ClassInterface(ClassInterfaceType.None)]
public class Bar : IBar {
    // etc...
}

它支持早期和晚期绑定,是一种隐藏类实现细节的好方法,一个强大的COM目标,避免从Bar的基类,System.Object方法中拉入的包袱。

答案 1 :(得分:0)

你需要返回一个ComVisible(和可枚举)的类,例如:

public Array Bars()
{
    return bars;
}

ArrayList,如下所示:

public ArrayList Bars()
{
    ArrayList list = new ArrayList();
    // etc...
    return list;
}

或者如果你不喜欢ArrayList,就像这样:

public BarList Bars()
{
    BarList list = new BarList();
    // etc...
    return list;
}

[ComVisible(true)]
public class BarList : List<Bar>
{
}