C ++ / CLI Conversión de System :: String ^ a std :: string

¿Alguien puede publicar un código simple que convierta,

System::String^ 

A,

C ++ std::string

Es decir, solo quiero asignar el valor de,

 String^ originalString; 

A,

 std::string newString; 

Consulte System::Runtime::InteropServices::Marshal::StringToCoTaskMemUni() y sus amigos.

Lo siento, no puedo publicar el código ahora; No tengo VS en esta máquina para verificar que se compile antes de publicar.

No haga rodar el suyo, use estas prácticas (y extensibles) envolturas proporcionadas por Microsoft.

Por ejemplo:

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

Puedes hacer esto fácilmente de la siguiente manera

 #include  System::String^ xyz="Hi boys"; std::string converted_xyz=msclr::interop::marshal_as< std::string >( xyz); 

Esto funcionó para mí:

 #include  #include  #include  //.. using namespace msclr::interop; //.. System::String^ clrString = (TextoDeBoton); std::string stdString = marshal_as(clrString); //String^ to std //System::String^ myString = marshal_as(MyBasicStirng); //std to String^ prueba.CopyInfo(stdString); //MyMethod //.. //Where: String^ = TextoDeBoton; //and stdString is a "normal" string; 

Aquí hay algunas rutinas de conversión que escribí hace muchos años para un proyecto de c ++ / cli, todavía deberían funcionar.

 void StringToStlWString ( System::String const^ s, std::wstring& os) { String^ string = const_cast(s); const wchar_t* chars = reinterpret_cast((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(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; } 

Pasé horas intentando convertir un valor de ToString de list box de formulario de Windows a una cadena estándar para poder usarlo con fstream para enviar a un archivo txt. My Visual Studio no incluía los archivos de encabezado de Marshal, que respondían varias respuestas que encontré usar. Después de tanto ensayo y error, finalmente encontré una solución al problema que solo usa System :: 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; 

Y aquí está la página de MSDN con el ejemplo: http://msdn.microsoft.com/en-us/library/1b4az623(v=vs.80).aspx

Sé que es una solución bastante simple, pero esto me llevó HORAS de solución de problemas y visitar varios foros para finalmente encontrar algo que funcionara.

Encontré una manera fácil de obtener una std :: string de String ^ es usar sprintf ().

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

¡No es necesario llamar a las funciones de Marshal!

ACTUALIZACIÓN Gracias a Eric, he modificado el código de muestra para verificar el tamaño de la cadena de entrada para evitar el desbordamiento del buffer.

C # usa el formato UTF16 para sus cadenas.
Entonces, además de convertir los tipos, también debe ser consciente del formato real de la cadena.

Al comstackr para el conjunto de caracteres de múltiples bytes Visual Studio y la API de Windows asumen UTF8 (En realidad, la encoding de Windows que es Windows-28591 ).
Al comstackr para el conjunto de caracteres Unicode Visual Studio y la API de Win asumen UTF16.

Por lo tanto, también debe convertir la cadena de formato UTF16 a UTF8, y no solo convertir a std :: string.
Esto será necesario cuando trabaje con formatos de caracteres múltiples, como algunos idiomas no latinos.

La idea es decidir que std::wstring siempre represente a UTF16 .
Y std::string siempre representa UTF8 .

Esto no se aplica por el comstackdor, es más una buena política que tener.

 #include "stdafx.h" #include  #include  #include  using namespace System; int main(array ^args) { System::String^ managedString = "test"; msclr::interop::marshal_context context; //Actual format is UTF16, so represent as wstring std::wstring utf16NativeString = context.marshal_as(managedString); //C++11 format converter std::wstring_convert> convert; //convert to UTF8 and std::string std::string utf8NativeString = convert.to_bytes(utf16NativeString); return 0; } 

O tenerlo en una syntax más compacta:

 int main(array ^args) { System::String^ managedString = "test"; msclr::interop::marshal_context context; std::wstring_convert> convert; std::string utf8NativeString = convert.to_bytes(context.marshal_as(managedString)); return 0; } 

Me gusta mantenerme alejado del mariscal.

 Using CString newString(originalString); 

Parece mucho más limpio y más rápido para mí. No necesita preocuparse por crear y eliminar un contexto.

// Utilicé VS2012 para escribir a continuación code– convert_system_string a Standard_Sting

  #include "stdafx.h" #include  #include  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; }