Domanda

Può qualcuno si prega di inviare un semplice codice che convertirebbe,

System::String^

Per,

C ++ std::string

vale a dire., Voglio solo assegnare il valore,

String^ originalString;

Per,

std::string newString;
È stato utile?

Soluzione

Scopri System::Runtime::InteropServices::Marshal::StringToCoTaskMemUni() e dei suoi amici.

Spiacenti non può inviare il codice ora; Non ho VS su questa macchina per controllare che compila prima dell'inserimento.

Altri suggerimenti

Non roll your own, utilizzare questi a portata di mano (e estensibile) involucri forniti da Microsoft.

Ad esempio:

#include <msclr\marshal_cppstd.h>

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

Si può facilmente fare questo nel modo seguente

#include <msclr/marshal_cppstd.h>

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

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

Questo ha funzionato per me:

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

Qui ci sono alcune routine di conversione che ho scritto molti anni fa per un c ++ / CLI progetto, che dovrebbe ancora funzionare.

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

Ho passato ore a cercare di convertire un valore casella di riepilogo ToString Windows Form in una stringa standard in modo che ho potuto usarlo con fstream per output in un file txt. Il mio Visual Studio non è venuto con i file di intestazione maresciallo che più risposte ho trovato detto da utilizzare. Dopo tanto tentativi ed errori ho finalmente trovato una soluzione al problema che utilizza solo sistema :: 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;

E qui è la pagina di MSDN con l'esempio: http://msdn.microsoft.com/en-us/library/1b4az623 (v = vs.80) aspx

Lo so che è una soluzione abbastanza semplice ma questo mi ore di risoluzione dei problemi e di visitare diversi forum per trovare finalmente qualcosa che ha funzionato preso.

Ho trovato un modo semplice per ottenere uno std :: string da una stringa ^ è quello di utilizzare sprintf ().

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

Non c'è bisogno di richiamare le funzioni maresciallo!

Aggiorna Grazie a Eric, ho modificato il codice di esempio per verificare la dimensione della stringa di input per evitare buffer overflow.

C # utilizza il formato UTF16 per le sue corde.
Così, oltre ad una semplice conversione dei tipi, si dovrebbe anche essere consapevole di formato effettivo della stringa.

Quando compila per Multi-byte Character set Visual Studio e l'API Win assume UTF8 (In realtà codifica finestre che è di Windows-28591 ).
Quando si compila per Unicode Character set Visual Studio e l'API Win assumere UTF16.

Quindi, è necessario convertire la stringa da UTF16 in formato UTF8 pure, e non solo la conversione a std :: string.
Questo diventerà necessaria quando si lavora con i formati multi-personaggio come alcune lingue non latine.

L'idea è quella di decidere che std::wstring sempre rappresenta UTF16 .
E std::string sempre rappresenta UTF-8 .

Questo non viene applicata dal compilatore, è più di una buona politica di avere.

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

o fa in una sintassi più compatta:

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

mi piace stare lontano dalla marshaller.

Using CString newString(originalString);

Sembra molto più pulito e più veloce per me. Non c'è bisogno di preoccuparsi per la creazione e l'eliminazione di un contesto.

// Ho usato VS2012 di scrivere sotto code-- convert_system_string a 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;
        }
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top