webentwicklung-frage-antwort-db.com.de

C++/CLI Konvertierung von System :: String ^ in std :: string

Kann jemand bitte einen einfachen Code posten, der konvertiert,

System::String^

Zu,

C++ std::string

Ich möchte nur den Wert von zuweisen,

String^ originalString;

Zu,

std::string newString;
80
sivabudh

Schauen Sie sich System::Runtime::InteropServices::Marshal::StringToCoTaskMemUni() und seine Freunde an.

Sorry kann jetzt keine Postleitzahl eingeben; Ich habe kein VS auf diesem Rechner, um die Kompilierung vor dem Posten zu überprüfen.

38
Martin

Rollen Sie nicht selbst, verwenden Sie diese praktische (und erweiterbare) Wrapper, die von Microsoft bereitgestellt werden.

Zum Beispiel:

#include <msclr\marshal_cppstd.h>

System::String^ managed = "test";
std::string unmanaged = msclr::interop::marshal_as<std::string>(managed);
132
tragomaskhalos

Sie können dies einfach wie folgt tun

#include <msclr/marshal_cppstd.h>

System::String^ xyz="Hi boys"; 

std::string converted_xyz=msclr::interop::marshal_as< std::string >( xyz);
36

Das hat für mich funktioniert:

#include <stdlib.h>
#include <string.h>
#include <msclr\marshal_cppstd.h>
//..
using namespace msclr::interop;
//..
System::String^ clrString = (TextoDeBoton);
std::string stdString = marshal_as<std::string>(clrString); //String^ to std
//System::String^ myString = marshal_as<System::String^>(MyBasicStirng); //std to String^
prueba.CopyInfo(stdString); //MyMethod
//..
//Where: String^ = TextoDeBoton;
//and stdString is a "normal" string;
19
Alejandro Perea

Hier sind einige Konvertierungsroutinen, die ich vor vielen Jahren für ein c ++/cli-Projekt geschrieben habe: sollte funktionieren immer noch.

void StringToStlWString ( System::String const^ s, std::wstring& os)
    {
        String^ string = const_cast<String^>(s);
        const wchar_t* chars = reinterpret_cast<const wchar_t*>((Marshal::StringToHGlobalUni(string)).ToPointer());
        os = chars;
        Marshal::FreeHGlobal(IntPtr((void*)chars));

    }
    System::String^ StlWStringToString (std::wstring const& os) {
        String^ str = gcnew String(os.c_str());
        //String^ str = gcnew String("");
        return str;
    }

    System::String^ WPtrToString(wchar_t const* pData, int length) {
        if (length == 0) {
            //use null termination
            length = wcslen(pData);
            if (length == 0) {
                System::String^ ret = "";
                return ret;
            }
        }

        System::IntPtr bfr = System::IntPtr(const_cast<wchar_t*>(pData));
        System::String^ ret = System::Runtime::InteropServices::Marshal::PtrToStringUni(bfr, length);
        return ret;
    }

    void Utf8ToStlWString(char const* pUtfString, std::wstring& stlString) {
        //wchar_t* pString;
        MAKE_WIDEPTR_FROMUTF8(pString, pUtfString);
        stlString = pString;
    }

    void Utf8ToStlWStringN(char const* pUtfString, std::wstring& stlString, ULONG length) {
        //wchar_t* pString;
        MAKE_WIDEPTR_FROMUTF8N(pString, pUtfString, length);
        stlString = pString;
    }
9
Ben Schwehn

Ich habe stundenlang versucht, einen ToString-Wert eines Windows-Formularlistenfelds in eine Standardzeichenfolge zu konvertieren, damit ich ihn mit fstream zur Ausgabe in eine TXT-Datei verwenden konnte. Mein Visual Studio enthielt keine Marshall-Header-Dateien, die von mehreren Antworten verwendet wurden. Nach so viel Ausprobieren habe ich endlich eine Lösung für das Problem gefunden, das nur System :: Runtime :: InteropServices verwendet:

void MarshalString ( String ^ s, string& os ) {
   using namespace Runtime::InteropServices;
   const char* chars = 
      (const char*)(Marshal::StringToHGlobalAnsi(s)).ToPointer();
   os = chars;
   Marshal::FreeHGlobal(IntPtr((void*)chars));
}

//this is the code to use the function:
scheduleBox->SetSelected(0,true);
string a = "test";
String ^ c = gcnew String(scheduleBox->SelectedItem->ToString());
MarshalString(c, a);
filestream << a;

Und hier ist die MSDN-Seite mit dem Beispiel: http://msdn.Microsoft.com/en-us/library/1b4az623(v=vs.80).aspx

Ich weiß, dass es eine ziemlich einfache Lösung ist, aber dafür brauchte ich STUNDEN für die Fehlerbehebung und den Besuch mehrerer Foren, um endlich etwas zu finden, das funktionierte.

5
Joe

Ich habe einen einfachen Weg gefunden, einen std :: string aus einem String zu bekommen, indem ich sprintf () verwende. 

char cStr[50] = { 0 };
String^ clrString = "Hello";
if (clrString->Length < sizeof(cStr))
  sprintf(cStr, "%s", clrString);
std::string stlString(cStr);

Kein Aufruf der Marshal-Funktionen!

UPDATEDank Eric habe ich den Beispielcode geändert, um die Größe der Eingabezeichenfolge zu überprüfen, um einen Pufferüberlauf zu verhindern.

4
Ionian316

C # verwendet das UTF16-Format für seine Zeichenfolgen.
Neben dem Konvertieren der Typen sollten Sie sich auch über das tatsächliche Format der Zeichenfolge im Klaren sein.

Beim Kompilieren für Multi-Byte-Zeichensatz setzt Visual Studio und die Win-API UTF8 (eigentlich Windows-Kodierung, die Windows-28591 ist).
Beim Kompilieren für Unicode-Zeichensatz Visual Studio und die Win-API wird UTF16 angenommen.

Daher müssen Sie die Zeichenfolge auch vom UTF16-Format in das UTF8-Format konvertieren und nicht nur in std :: string konvertieren.
Dies wird erforderlich, wenn Sie mit mehreren Zeichenformaten wie einigen nicht-lateinischen Sprachen arbeiten.

Die Idee ist zu entscheiden, dass std::wstringimmerUTF16 darstellt.
Und std::stringimmer steht für UTF8

Dies wird vom Compiler nicht erzwungen, es ist eher eine gute Richtlinie. 

#include "stdafx.h"
#include <string>
#include <codecvt>
#include <msclr\marshal_cppstd.h>

using namespace System;

int main(array<System::String ^> ^args)
{
    System::String^ managedString = "test";

    msclr::interop::marshal_context context;

    //Actual format is UTF16, so represent as wstring
    std::wstring utf16NativeString = context.marshal_as<std::wstring>(managedString); 

    //C++11 format converter
    std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> convert;

    //convert to UTF8 and std::string
    std::string utf8NativeString = convert.to_bytes(utf16NativeString);

    return 0;
}

Oder haben Sie es in einer kompakteren Syntax:

int main(array<System::String ^> ^args)
{
    System::String^ managedString = "test";

    msclr::interop::marshal_context context;
    std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> convert;

    std::string utf8NativeString = convert.to_bytes(context.marshal_as<std::wstring>(managedString));

    return 0;
}
3
Yochai Timmer

Ich halte mich gerne vom Marschaller fern.

Using CString newString(originalString);

Scheint mir viel sauberer und schneller. Sie müssen sich keine Sorgen um das Erstellen und Löschen eines Kontexts machen.

0
LL.

// Ich habe VS2012 verwendet, um unten Code-- convert_system_string nach Standard_Sting zu schreiben

        #include "stdafx.h"
        #include <iostream>
        #include <string> 

        using namespace System;
        using namespace Runtime::InteropServices; 


        void MarshalString ( String^ s, std::string& outputstring )
        {  
           const char* kPtoC =  (const char*) (Marshal::StringToHGlobalAnsi(s)).ToPointer();                                                        
           outputstring = kPtoC;  
           Marshal::FreeHGlobal(IntPtr((void*)kPtoC));  
        }   

        int _tmain(int argc, _TCHAR* argv[])
        {
             std::string strNativeString;  
             String ^ strManagedString = "Temp";

             MarshalString(strManagedString, strNativeString);  
             std::cout << strNativeString << std::endl; 

             return 0;
        }
0
Praveer Kumar