How to pass a list of objects from C++ to C#?

4.5k views Asked by At

My first question here :)

I am working with an application written in C++ (a map editor for a game) that has the front end UI written in C#. Since i'm new to C# i'm trying to do as much as possible on the C++ side.

From C# i want to call a C++ function that will return a list of structs with simple variable types (int and string) so that i can populate a listBox i have in the UI with them. Is this possible? How should i write the dll import function in C#?

I have tried searching here for the answer, but i only found post on how to pass lists from C# to C++.

The C++ code:

struct PropData
{
PropData( const std::string aName, const int aId )
{
    myName = aName;
    myID = aId;
}

std::string myName;
int myID;
};

extern "C" _declspec(dllexport) std::vector<PropData> _stdcall GetPropData()
{
std::vector<PropData> myProps;

myProps.push_back( PropData("Bush", 0) );
myProps.push_back( PropData("Tree", 1) );
myProps.push_back( PropData("Rock", 2) );
myProps.push_back( PropData("Shroom", 3) );

return myProps;
}

The C# import function:

    [DllImport("MapEditor.dll")]
    static extern ??? GetPropData();

EDIT:

After the post from Ed S. I changed the c++ code to struct PropData { PropData( const std::string aName, const int aId ) { myName = aName; myID = aId; }

    std::string myName;
    int myID;
};

extern "C" _declspec(dllexport) PropData* _stdcall GetPropData()
{
    std::vector<PropData> myProps;

    myProps.push_back( PropData("Bush", 0) );
    myProps.push_back( PropData("Tree", 1) );
    myProps.push_back( PropData("Rock", 2) );
    myProps.push_back( PropData("Shroom", 3) );

    return &myProps[0];
}

and the C# to [DllImport("MapEditor.dll")] static extern PropData GetPropData();

    struct PropData
    {
        string myName;
        int myID;
    }

    private void GetPropDataFromEditor()
    {
        List<PropData> myProps = GetPropData();
    }

but of course this doesn't compile as GetPropData() doesn't return anything that translates to a list.

Thanks a lot Ed S. for getting me this far!

1

There are 1 answers

5
Ed Swangren On BEST ANSWER

You're not going to be able to marshall the std::vector into C# territory. What you should do instead is return an array. Sticking to basic types makes things a lot more simple when facing interop situations.

std::vector guarantees that &v[0] points to the first element and that all elements are stored contiguously, so just pass the array back. If you're stuck with the C++ interface as it is (which I don't think you are) you will have to look into some more complex mechanism like COM.