Frage

Kann jemand bitte einen einfachen Code schreiben, die umwandeln würde,

System::String^

C ++ std::string

d., Ich will nur den Wert,

zuweisen
String^ originalString;

std::string newString;
War es hilfreich?

Lösung

Überprüfen Sie heraus System::Runtime::InteropServices::Marshal::StringToCoTaskMemUni() und seine Freunde.

Es kann keinen Code schreiben jetzt; Ich habe VS nicht auf dieser Maschine vor der Veröffentlichung kompiliert es zu überprüfen.

Andere Tipps

Sie Ihre eigenen nicht rollen, verwenden Sie diese praktisch (und erweiterbar) Wrapper bereitgestellt von Microsoft.

Zum Beispiel:

#include <msclr\marshal_cppstd.h>

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

Sie können ganz einfach tun dies wie folgt

#include <msclr/marshal_cppstd.h>

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

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

Das funktioniert für mich:

#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;

Hier einige Konvertierungsroutinen sind ich für eine c vor vielen Jahren schrieb ++ / cli Projekt, sie sollte immer noch funktionieren.

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;
    }

Ich verbrachte Stunden damit, einen Windows-Form listbox ToString Wert auf eine Standardzeichenfolge konvertieren, so dass ich es mit fstream zur Ausgabe in eine txt-Datei verwenden konnte. Mein Visual Studio kam nicht mit Marschall-Header-Dateien, die mehr Antworten, die ich sagten gefunden zu verwenden. Nach so viel Versuch und Irrtum fand ich endlich eine Lösung für das Problem, das System-nur verwendet :: Runtime :: InteropServices:

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ß, es ist eine ziemlich einfache Lösung, aber das hat mich Stunden der Fehlersuche und mehreren Foren besuchen endlich etwas zu finden, die funktioniert.

Ich fand eine einfache Möglichkeit, einen std :: string aus einem String zu bekommen ^ ist sprintf () zu verwenden.

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

keine Notwendigkeit, die Marshal-Funktionen aufzurufen!

UPDATE Dank Eric, ich habe den Beispielcode geändert für die Größe der Eingabezeichenfolge zu überprüfen Pufferüberlauf zu verhindern.

C # verwendet das UTF16-Format für die Saiten.
Also, neben nur die Typen konvertieren, sollten Sie auch über die Zeichenfolge der aktuelle Format bewusst sein.

Wenn für Multi-Byte Character Kompilieren gesetzt Visual Studio und die Win-API übernimmt UTF8 (Eigentlich Windows-Kodierung, die ist Fenster-28591 ).
Beim Kompilieren für Unicode-Zeichensatz Visual Studio und das Win-API UTF16 übernehmen.

So müssen Sie die Zeichenfolge von UTF16 zu UTF8-Format konvertieren als auch, und nicht nur konvertieren std :: string.
Dies wird notwendig werden, wenn mit mehreren Zeichenformaten wie einige nicht-lateinischen Sprachen zu arbeiten.

Die Idee ist, dass std::wstring zu entscheiden, immer für UTF16 .
Und std::string immer für UTF8 .

Dies wird durch den Compiler nicht erzwungen, es ist eher eine gute Politik zu haben.

#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 hat 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;
}

Ich mag vom Einweiser zu.

Using CString newString(originalString);

Es scheint viel sauberer und schneller zu mir. Kein Grund zur Sorge über das Erstellen und Löschen eines Kontext.

// verwendete ich VS2012 unten zu schreiben code-- convert_system_string zu Standard_Sting

        #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;
        }
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top