2008-09-11 5 views
40

Was ist die bewährte Möglichkeit, von char * zu System :: String und zurück in C++/CLI zu konvertieren? Ich habe ein paar Verweise auf marschall_to <> Vorlagenfunktionen auf Google gefunden, aber es scheint, dass diese Funktion nie den Schnitt für Visual Studio 2005 gemacht hat (und nicht in Visual Studio 2008, AFAIK). Ich habe auch Code auf Stan Lippman's blog gesehen, aber es ist von 2004. Ich habe auch Marshal :: StringToHGlobalAnsi() gesehen. Gibt es eine Methode, die als "best practice" gilt?Was ist die beste Methode zum Konvertieren zwischen char * und System :: String in C++/CLI

Antwort

18

Es gibt einen guten Überblick hier (die Marshalling-Unterstützung hinzugefügt für VS2008): http://www.codeproject.com/KB/mcpp/OrcasMarshalAs.aspx

+7

Danke, aber das ist eine lange Erklärung. Das geht mehr auf den Punkt: '#include // marshal_context context; // my_c_string = context.marshal_as (my_csharp_string); ' – gatopeich

+0

Für diejenigen, die sich wundern, ist der vollständige Namespace für Kontext' Msclr :: interop :: marschall_context' – Mugen

1

Was wir getan haben, ist ein C++ \ CLI-Objekt, das die Zeichenfolge in nicht manipuliertem Code enthielt und veraltete Kopien des Elements ausgeben würde. Der Umwandlungscode sieht sehr ähnlich aus wie Stan auf seinem Blog (ich kann mich nicht genau daran erinnern) (Wenn Sie seinen Code verwenden, stellen Sie sicher, dass Sie ihn aktualisieren, um delete []) zu verwenden, aber wir haben sichergestellt, dass der Destruktor die Freigabe übernimmt die nicht gemanagten Elemente des Objekts. Dies ist ein wenig übertrieben, aber wir hatten keine Lücken, als wir uns in Legacy-C++ - Codemodule einklinkten.

70

System :: String hat einen Konstruktor, der ein Zeichen nimmt *:

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

ein Zeichen bekommen * zurück ist ein bisschen härter, aber nicht so schlecht:

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

+1, System :: String-Konstruktor dauert auch Länge und Codierung! –

+5

'Marshal :: StringToHGlobalAnsi' ist eine schlechte Option im Vergleich zu' marshal_context' (wie von Matthew erwähnt), die RAII verwendet, um den Puffer automatisch zu befreien. Ganz zu schweigen davon, dass der Name völlig falsch ist, es gibt kein 'HGLOBAL' zurück. –

1

Ich habe ein paar Hilfsmethoden erstellt. Ich musste dies tun, um von einer alten Qt-Bibliothek zu CLI String zu wechseln. Wenn jemand das hinzufügen und mir sagen kann, ob es so aussieht, als ob ich ein Speicherleck hätte und was ich tun könnte, um es zu beheben, wäre ich sehr dankbar.

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

Wahrscheinlich muss Marshal :: FreeHGlobal (IntPtr ((void *) Zeichen)); es –

+0

@Pat ja Entschuldigung, ich sollte dies nach diesem Update aktualisiert haben. Ich habe es jetzt gut funktioniert. Durch die Umstellung auf .NET wurde die Leistung dieser App um das Dreifache gesteigert. Selbst Marshalling Dinge herum. – dko

Verwandte Themen