3

I need to have a function in C++/CLI which do the link between a C++ native std::list<std::string> and a string[] in C# to do something like that with my WinForm :

    ComboBox1.Items.AddRange(installs);

installs is the string[].

Do you have an idea? How can I do this? C++/CLI programming is hard without Intellisense. :(

What do you think about this?

Native C++ .cpp

std::list<std::string>* Get_Liste_place_de_marche(void)
{
    list<string>* liste_place_de_marche = new list<string>;
    liste_place_de_marche->push_back("CAC 40");
    liste_place_de_marche->push_back("DAX");
    return liste_place_de_marche;
}

And I need to code this function using the last code to the top :

C++/CLI .cpp called in my Winform with C#

array<System::String^>^ NativeMethod::Get_Liste_place_de_marche(void)
{
    typedef std::list<std::string>::const_iterator iter_t;

    std::list<std::string> const* list = new std::list<std::string>;
    list = ::Get_Liste_place_de_marche();

    array<System::String^>^ ret = gcnew array<System::String^>(list->size());
    int j = 0;

    for (iter_t i = list->begin(); i != list->end(); ++i)
        ret[j++] = gcnew System::String(i->c_str());

    return ret;
}

It should work? Because I have many errors...

bdelmas
  • 922
  • 2
  • 12
  • 20

1 Answers1

4

The following should do the job:

array<System::String^>^ ArrayFromList(std::list<std::string> const& list) {
    typedef std::list<std::string>::const_iterator iter_t;

    array<System::String^>^ ret = gcnew array<System::String^>(list.size());
    int j = 0;

    for (iter_t i = list.begin(); i != list.end(); ++i)
        ret[j++] = gcnew System::String(i->c_str());

    return ret;
}

I would try to keep this more general, though. For instance, it’s customary in C++ to work on iterator ranges instead of containers. Furthermore, the above only works on (zero-terminated) strings. Very similar code will be needed to convert other object collections. It might make sense to abstract the object conversion away.

ildjarn
  • 62,044
  • 9
  • 127
  • 211
Konrad Rudolph
  • 530,221
  • 131
  • 937
  • 1,214
  • 1
    @Konrad : `System.String` is nonsensical here, and `cli::array::operator[]`'s argument is `int` so `j` should be signed for consistency. – ildjarn Jun 29 '11 at 15:10
  • @Nazka : It will work if you change `System.String` to `System::String`, and as I mentioned in my other comment, `j` should be of type `int` rather than `unsigned` (though this isn't strictly necessary in order to get the code to compile). – ildjarn Jun 29 '11 at 15:20
  • @ildjarn Sorry, the `System.String` was an accident. As for unsigned, you’re right but it’s the CLI that is “wrong” here. Call it idiosyncrasy … since C++ does it right and make indices unsigned. – Konrad Rudolph Jun 29 '11 at 15:26
  • 1
    @Konrad : Agreed, but this is C++/CLI not C++, so idiosyncrasies aside... ;-] Also, you still have `array^ ret`. – ildjarn Jun 29 '11 at 15:37
  • When I compile I have many errors. `"C2556: 'cli::array ^Get_Liste_place_de_marche(void)' : overloaded function differs only by return type from 'std::list<_Ty> *Get_Liste_place_de_marche(void)'"` | `C2491: 'Get_Liste_place_de_marche' : definition of dllimport function not allowed` | `error C2440: '=' : cannot convert from 'std::list<_Ty> *(__cdecl *)(void)' to 'std::list<_Ty> *'` It's for `list = ::Get_Liste_place_de_marche();` Line 4. It's ugly I know but I can't add lines in comment :s – bdelmas Jun 29 '11 at 15:40
  • @Nazka The error message says you exactly what’s wrong: your two functions cannot have the same name. Apart from that your usage of `list` isn’t meaningful. Please don’t use pointers here. – Konrad Rudolph Jun 29 '11 at 15:43
  • @Konrad Rudolph ah yes I understand I forget to put `NativeMethod::Get_Liste_place_de_marche` and not just `Get_Liste_place_de_marche`. How I do without pointers? It's work when I compile. – bdelmas Jun 29 '11 at 15:48
  • 2
    @Nazka it works but it leaks memory like crazy. Just omit the pointers and the calls to `new`. Oh, and [get a good beginner’s C++ book](http://stackoverflow.com/q/388242/1968) because this is one of the things that you *need to know* as a C++ developer. – Konrad Rudolph Jun 29 '11 at 15:51