我有一个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()',我想这就是为什么它不知道如何处理它。
我可以做些什么来完成这项工作?
答案 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>
{
}