How to return an array of .NET objects via a COM method

2

I have a .NET assembly. It happens to be written in C++/CLI. I am exposing a few objects via COM. Everything is working fine, but I cannot for the life of me figure out how to return an array of my own objects from a method. Every time I do, I get a type mismatch error at runtime. I can return an array of ints or strings just fine.

Here is my main class

[Guid("7E7E69DD-blahblah")]
[ClassInterface(ClassInterfaceType::None)]
[ComVisible(true)]
public ref class Foo sealed : IFoo
{
public:
    virtual array<IBar^>^ GetStuff();
}

[Guid("21EC1AAA-blahblah")]
[InterfaceType(ComInterfaceType::InterfaceIsIDispatch)]
[ComVisible(true)]  
public interface class IFoo
{
public:
    virtual array<IBar^>^ GetStuff()
    {
        // For simplicity, return an empty array for now.
        return gcnew array<IBar^>(0);
    }
};

Here is the class I am returning

[Guid("43A37BD4-blahblah")]
[InterfaceType(ComInterfaceType::InterfaceIsIDispatch)]
[ComVisible(true)]  
public interface class IBar
{
    // Completely empty class, just for testing.  
    //In real life, I would like to return two strings and an int.
};

[Guid("634708AF-blahblah")]
[ClassInterface(ClassInterfaceType::None)]
[ComVisible(true)]
[Serializable]
public ref class Bar : IBar
{
};

This is my (native) C++ code that calls it:

MyNamespace::IFooPtr session(__uuidof(MyNamespace::Foo));
// For simplicity, don't even check the return.
session->GetStuff();

Calling GetStuff() gets me a _com_error 0x80020005 (DISP_E_TYPEMISMATCH). I can tell my method is being called correctly, it's just that when .NET/COM goes to marshall the return, it chokes. As I said, it works fine with arrays of ints or strings. What do I have to do to my class to allow it to be returned in an array?

As it happens, my class will only contain a couple of strings and an int (no methods), if that makes it any easier. Obviously I've tried returning a non-empty array and classes that actually contain some data, this is just the simplest case that illustrates the problem.

.net
com
c++-cli
com-interop
safearray
asked on Stack Overflow Nov 16, 2009 by mhenry1384

1 Answer

0

You need to implement IDispatch and the Enumerator method

public ref class FooCollection{
[DispId(-4)]
public IEnumerator^ GetEnumerator()
{
//...
}
}
answered on Stack Overflow Nov 17, 2009 by Sheng Jiang 蒋晟 • edited Nov 29, 2011 by Jason Plank

User contributions licensed under CC BY-SA 3.0