2010-08-21 36 views
6

Así que trabajo en clr, creando .NET dll en Visual C++.Cómo convertir System :: String^en std :: string?

I Tru dicho código:

static bool InitFile(System::String^ fileName, System::String^ container) 
{ 
    return enc.InitFile(std::string(fileName), std::string(container)); 
} 

tener codificador que resives normaly std :: string. pero aquí el compilador (estudio visual) me da un error C2664 si elimino argumentos de std :: string y C2440, que en general es el mismo. VS me dice que simplemente no puede convertir System :: String^en std :: string.

Así que estoy triste ... ¿qué debo hacer para convertir System :: String^en std :: string?

Actualización:

Ahora, con su ayuda tengo dicho código

#include <msclr\marshal.h> 
#include <stdlib.h> 
#include <string.h> 
using namespace msclr::interop; 
namespace NSSTW 
{ 
    public ref class CFEW 
    { 
public: 
    CFEW() {} 

    static System::String^ echo(System::String^ stringToReturn) 
    { 
     return stringToReturn; 
    } 

    static bool InitFile(System::String^ fileName, System::String^ container) 
    { 
     std::string sys_fileName = marshal_as<std::string>(fileName);; 
     std::string sys_container = marshal_as<std::string>(container);; 
     return enc.InitFile(sys_fileName, sys_container); 
    } 
... 

pero cuando intento compilar me da C4996

error C4996: 'msclr :: :: interoperabilidad error_reporting_helper < _To_Type, _From_Type> :: marshal_as ': esta conversión no es compatible con la biblioteca o el archivo de encabezado necesario para esta conversión no está incluido. Consulte la documentación sobre 'Cómo: Extender la Biblioteca de Marshaling' para agregar su propio método de clasificación.

¿qué hacer?

+4

Ha incluido 'msclr \ marshal.h'. Pruebe 'msclr \ marshal_cppstd.h'. –

+0

@Chris Schmich: gracias - ahora se compila perfectamente =) – Rella

Respuesta

6

Si está utilizando VS2008 o posterior, puede hacerlo de manera muy sencilla con el automatic marshaling added to C++. Por ejemplo, puede convertir System::String^-std::string través marshal_as:

System::String^ clrString = "CLR string"; 
std::string stdString = marshal_as<std::string>(clrString); 

Este es el mismo utilizado para el cálculo de referencias P/Invoke llamadas.

+0

Me gusta la idea, pero ¿cómo declarar marshal_as en mi código? dónde y qué debo escribir para declararlo (para deshacerme del error C2065), uso VS2008 – Rella

+1

Para pasar de 'System :: String ^' a 'std :: string', necesitas' #include 'donde' marshal_as' es declarado. –

+0

cuando intento #include me da un error fatal C1083 ... así que edité el código y lo publiqué aquí en la Pregunta (uso lo que usaron en el ejemplo de MS MSDN) ... pueden echar un vistazo a Por favor. – Rella

4

Desde el artículo How to convert System::String^ to std::string or std::wstring en MSDN:

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

Uso:

std::string a; 
System::String^ yourString = gcnew System::String("Foo"); 
MarshalString(yourString, a); 
std::cout << a << std::endl; // Prints "Foo" 
3

Es necesario incluir marshal_cppstd.h para convertir a cadena^std :: string.

No mencione si le preocupan los caracteres no ascii. Si necesita unicode (y si no, ¿por qué no?), Hay un marshal_as que devuelve un std :: wstring.

Si está usando utf8, tendrá que hacer su propio diseño. Puede usar un bucle simple:

System::String^ s = ...; 
std::string utf8; 
for each(System::Char c in s) 
    // append encoding of c to "utf8"; 
Cuestiones relacionadas