views:

154

answers:

1

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.

A: 

you need to implement IDispatch and the Enumerator method public ref class FooCollection{ [DispId(-4)] public IEnumerator^ GetEnumerator() { //... } }

Sheng Jiang 蒋晟
So I can't just return an array, I have to write my own collection class and expose that? Disappointing, but I suppose not too difficult.
mhenry1384