2010-08-21 19 views
6

Quindi lavoro in clr, creando .net dll in visual C++.Come trasformare System :: String^in std :: string?

ho TRU tale codice:

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

avere encoder che resives normalmente std :: string. ma qui il compilatore (visual studio) mi dà errore C2664 se spoglio gli argomenti da std :: string e C2440 che è in generale lo stesso. VS mi dice che non riesce a convertire System :: String^in std :: string.

Quindi sono triste ... cosa devo fare per trasformare System :: String^in std :: string?

Aggiornamento:

ora con il vostro aiuto ho tale codice

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

ma quando provo a compilare mi dà C4996

errore C4996: 'msclr :: :: interoperabilità error_reporting_helper < _To_Type, _From_Type> :: marshal_as ': questa conversione non è supportata dalla libreria o il file di intestazione necessario per questa conversione non è incluso. Fare riferimento alla documentazione su "Come: estendere la libreria Marshalling" per aggiungere il proprio metodo di marshalling.

cosa fare?

+4

Hai incluso 'msclr \ marshal.h'. Prova 'msclr \ marshal_cppstd.h'. –

+0

@Chris Schmich: grazie - ora compila perfettamente =) – Rella

risposta

6

Se si utilizza VS2008 o più recente, è possibile farlo semplicemente con lo automatic marshaling added to C++. Ad esempio, è possibile convertire System::String^-std::string via marshal_as:

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

Questo è lo stesso utilizzato per marshalling P/Invoke chiamate.

+0

Mi piace l'idea ma come dichiarare marshal_as nel mio codice? dove e cosa devo scrivere per dichiararlo (per eliminare l'errore C2065), utilizzo VS2008 – Rella

+1

Per andare da 'System :: String ^' a 'std :: string', è necessario' #include 'dove' marshal_as' è dichiarato. –

+0

quando provo #include mi dà l'errore fatale C1083 ... quindi ho modificato il codice e l'ho postato qui in Domanda (uso quello che hanno usato nell'esempio MS MSDN) ... puoi dare un'occhiata a per favore. – Rella

4

Dall'articolo How to convert System::String^ to std::string or std::wstring su 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)); 
} 

Usage:

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

È necessario includere marshal_cppstd.h per convertire String^a std :: string.

Non parli se sei preoccupato per i caratteri non ascii. Se hai bisogno di unicode (e se no, perché no !?), c'è un marshal_as che restituisce uno std :: wstring.

Se si utilizza utf8, è necessario eseguire il rollover. È possibile utilizzare un ciclo semplice:

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