How can I call a method (COM object) that returns an array of objects from VBScript

I have a COM object 'Foo' that defines a function that returns an array Bar:

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

      

It's in a DLL that is registered with COM.

I can call it from VBA like this:

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

Dim oBar As Bar
Set oBar = aBars(0)

      

However, I need to call the same function from VBScript, which has no early binding support, and when I try to do that, it fails:

Dim aBars
aBars = oFoo.Bars()

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

      

If I check for type "aBars" it is "Unknown ()" and I wonder why it doesn't know what to do with it.

What can I do to make this work?

+3


source to share


2 answers


There is something wrong with the attributes of the Bar class or the interface, it does not implement IDispatch as a scripting language is required. Only IUnknown, something that VBA can handle, but VBScript cannot. IDispatch is required to support late binding if required for script runtime.

I don't see the Bar at all, so guess. If it is an interface or a class that implements the interface, you need [InterfaceType(ComInterfaceType.InterfaceIsDual)]

to get support for both early and late binding. Or ComInterfaceType.InterfaceIsIDispatch for late binding.

If it's a class, you need [ClassInterface(ClassInterfaceType.AutoDual)]

to get support for early and late times. Or ClassInterfaceType.AutoDispatch for lateness.



Boiler malfunction:

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

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

      

which supports both early and late binding, and is a good way to hide the implementation details of a class, a strong COM purpose, avoiding the baggage that is retrieved from the base Bar class, System.Object methods.

+1


source


You need to return a ComVisible (and enumerable) class , like this:

public Array Bars()
{
    return bars;
}

      

or ArrayList , something like this:



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

      

or if you don't like ArrayList, something like this:

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

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

      

0


source







All Articles