44 votes

Quel est le meilleur moyen de convertir entre char* et System::String en C++/CLI

Quelle est la manière approuvée de convertir de char* à System::string et vice versa en C++/CLI ? J'ai trouvé quelques références à des fonctions modèles marshal_to<> sur Google, mais il semble que cette fonctionnalité n'a jamais été incluse dans Visual Studio 2005 (et n'est pas non plus dans Visual Studio 2008, à ma connaissance). J'ai également vu du code sur le blog de Stan Lippman, mais c'était en 2004. J'ai également vu Marshal::StringToHGlobalAnsi(). Existe-t-il une méthode considérée comme "bonne pratique" ?

74voto

Ben Straub Points 3224

System::String a un constructeur qui prend un char* :

 using namespace system;
 const char* charstr = "Hello, world!";
 String^ clistr = gcnew String(charstr);
 Console::WriteLine(clistr);

Récupérer un char* est un peu plus difficile, mais pas trop compliqué :

 IntPtr p = Marshal::StringToHGlobalAnsi(clistr);
 char *pNewCharStr = static_cast(p.ToPointer());
 cout << pNewCharStr << endl;
 Marshal::FreeHGlobal(p);

5 votes

+1, Le constructeur de System::String prend également en compte la longueur et l'encodage!

6 votes

Marshal::StringToHGlobalAnsi est une mauvaise option par rapport à marshal_context (comme mentionné par Matthew), qui utilise RAII pour libérer automatiquement le tampon. Sans oublier que le nom est totalement faux, il ne renvoie pas du tout un HGLOBAL.

0 votes

Votre exemple ne fonctionne pas pour moi en C++ / CLI utilisant .NET 4.6.1. Il n'y a pas de constructeur System::String qui prend un char*... seulement signed char* ou wchar_t*

18voto

Matthew Clendening Points 603

Il y a un bon aperçu ici (ce support de marshal ajouté pour VS2008) : http://www.codeproject.com/KB/mcpp/OrcasMarshalAs.aspx

7 votes

Merci, mais c'est une explication assez longue. Voici une explication plus concise: #include // marshal_context context; // my_c_string = context.marshal_as(my_csharp_string);

0 votes

Pour ceux qui se demandent, l'espace de noms complet pour le contexte est msclr::interop::marshal_context

0voto

Dan Blair Points 1580

Ce que nous avons fait est de créer un objet C++\CLI qui contenait la chaîne de caractères dans le code non géré et renverrait des copies gérées de l'élément. Le code de conversion ressemble beaucoup à ce que Stan a sur son blog (je ne m'en souviens pas exactement) (Si vous utilisez son code, assurez-vous de le mettre à jour pour utiliser delete[]) mais nous nous sommes assurés que le destructeur s'occuperait de libérer tous les éléments non gérés de l'objet. C'est un peu exagéré mais nous n'avons pas eu de fuites lorsque nous avons connecté des modules de code C++ hérités.

0voto

dko Points 143

J'ai créé quelques méthodes d'aide. J'ai dû le faire pour passer d'une ancienne bibliothèque Qt à CLI String. Si quelqu'un peut ajouter quelque chose et me dire s'il semble que j'ai une fuite de mémoire et ce que je peux faire pour la corriger, je serais très reconnaissant.

void MarshalString (  String ^ s, wstring& os ) {
    using namespace Runtime::InteropServices;
    const wchar_t* caractère = (const wchar_t*)(Marshal::StringToHGlobalUni(s)).ToPointer();
    os = caractère;
}
QString SystemStringToQt( System::String^ str)
{
    wstring t;
    MarshalString(str, t);
    QString r = QString::fromUcs2((const ushort*)t.c_str());
    return r;
}

0 votes

Vous devrez probablement Marshal :: FreeHGlobal (IntPtr ((void *) chars)); cela

1 votes

@Pat oui désolé, j'aurais dû mettre à jour cela après. J'ai réussi à le faire fonctionner correctement maintenant. Le passer à .NET a augmenté les performances de cette application de 3 fois. Même le marshaling des données a été amélioré.

-1voto

Tadej Mali Points 150

Un lien supplémentaire vers un résumé des façons possibles :

http://support.microsoft.com/?kbid=311259

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X