C ++ .NET convierte System :: String a std :: string

¿Cómo se convierte System :: String a std :: string en C ++ .NET?

Hay una syntax más clara si está utilizando una versión reciente de .net

#include "stdafx.h" #include  #include  using namespace System; int main(array ^args) { System::String^ managedString = "test"; msclr::interop::marshal_context context; std::string standardString = context.marshal_as(managedString); return 0; } 

Esto también le brinda una mejor limpieza frente a las excepciones.

Hay un artículo msdn para otras conversiones

Y en respuesta a la “forma más fácil” en las versiones posteriores de C ++ / CLI, puede hacerlo sin el contexto marshal_context. Sé que esto funciona en Visual Studio 2010; no estoy seguro antes de eso.


 #include "stdafx.h" #include  #include  using namespace msclr::interop; int main(array ^args) { System::String^ managedString = "test"; std::string standardString = marshal_as(managedString); return 0; } 

 stdString = toss(systemString); static std::string toss( System::String ^ s ) { // convert .NET System::String to std::string const char* cstr = (const char*) (Marshal::StringToHGlobalAnsi(s)).ToPointer(); std::string sstr = cstr; Marshal::FreeHGlobal(System::IntPtr((void*)cstr)); return sstr; } 

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

Tuve demasiados errores ambiguos que aparecen con las respuestas anteriores (sí, soy un novato en C ++)

Esto funcionó para mí para enviar cadenas desde C # a C ++ CLI

DO#

 bool result; result = mps.Import(mpsToolName); 

CLI de C ++

función:

 bool ManagedMPS::Import(System::String^ mpsToolNameTest) std::string mpsToolName; mpsToolName = toStandardString(mpsToolNameTest); 

función que funciona desde la conversión de String ^ a std :: string

 static std::string toStandardString(System::String^ string) { using System::Runtime::InteropServices::Marshal; System::IntPtr pointer = Marshal::StringToHGlobalAnsi(string); char* charPointer = reinterpret_cast(pointer.ToPointer()); std::string returnString(charPointer, string->Length); Marshal::FreeHGlobal(pointer); return returnString; } 

EN MÁS INVESTIGACIÓN, parece que esto es más limpio y más seguro.

Cambié a usar este método en su lugar.

 std::string Utils::ToUnmanagedString(String^ stringIncoming) { std::string unmanagedString = marshal_as(stringIncoming); return unmanagedString; } 

Creando un componente de tiempo de ejecución de Windows que puede usar:

 String^ systemString = "Hello"; std::wstring ws1(systemString ->Data()); std::string standardString(ws1.begin(), ws1.end());