7

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!

Cousken
  • 160
  • 2
  • 10

1 Answers1

9

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.

Ed S.
  • 115,705
  • 20
  • 165
  • 244
  • Couldn't he could also use a structure? Of course it would be fair easier to do everything in one language. If the front-end is written in C# it should be possible to do everything in C#. – Security Hound Jan 18 '12 at 17:57
  • Thank you for the quick answere, but i need more help with the C# syntax, as i said i'm new to the language (just started today), i didn't even know it could handle pointers. – Cousken Jan 18 '12 at 18:00
  • @Ramhound: I don't see how you will be able to create a C# structure that mimics a `std::vector` exactly. That only works for POD types. – Ed S. Jan 18 '12 at 18:07
  • @Cousken: Well, it's complicated by the fact that you are filling the vector with `PropData` objects, so you would need to mimic those as well. You should be able to create a struct to mimic that as well. Pinvoke.net is a great resource here. – Ed S. Jan 18 '12 at 18:09
  • @Ed S.: I could split the PropData objects into an array of ints and strings, and the strings into an array of chars... i'll try that when i get to work today. Alternativley i can export that list to XML and then read it in my C# UI. – Cousken Jan 19 '12 at 10:22