¿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;
Respuestas:
No enrolle el suyo, use estos prácticos (y extensibles) contenedores proporcionados por Microsoft.
Por ejemplo:
#include <msclr\marshal_cppstd.h>
System::String^ managed = "test";
std::string unmanaged = msclr::interop::marshal_as<std::string>(managed);
Puede hacer esto fácilmente de la siguiente manera
#include <msclr/marshal_cppstd.h>
System::String^ xyz="Hi boys";
std::string converted_xyz=msclr::interop::marshal_as< std::string >( xyz);
Esto funcionó para mí:
#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;
Aquí hay algunas rutinas de conversión que escribí hace muchos años para un proyecto c ++ / cli, aún deberían funcionar.
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;
}
Pasé horas tratando de convertir un valor ToString de listbox de Windows Form a una cadena estándar para poder usarlo con fstream para generar un archivo txt. Mi Visual Studio no venía con archivos de encabezado marshal que varias respuestas que encontré decían 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 tomó HORAS de resolución de problemas y visitar varios foros para finalmente encontrar algo que funcionó.
Encontré una manera fácil de obtener un std :: string de un 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 Marshal!
ACTUALIZACIÓN Gracias a Eric, modifiqué el código de muestra para verificar el tamaño de la cadena de entrada para evitar el desbordamiento del búfer.
C # usa el formato UTF16 para sus cadenas.
Por lo tanto, además de convertir los tipos, también debe ser consciente del formato real de la cadena.
Al compilar para el conjunto de caracteres de varios bytes, Visual Studio y la API de Win asumen UTF8 (en realidad, la codificación de Windows es Windows-28591 ).
Al compilar para el juego 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 convertirla a std :: string.
Esto será necesario cuando trabaje con formatos de varios caracteres como algunos idiomas no latinos.
La idea es decidir que std::wstring
siempre representa UTF16 .
Y std::string
siempre representa UTF8 .
Esto no es impuesto por el compilador, es más una buena política.
#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 tenerlo en una sintaxis más compacta:
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;
}
// Usé VS2012 para escribir el siguiente código: 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;
}