Antworten:
Rollen Sie nicht Ihre eigenen, sondern verwenden Sie diese praktischen (und erweiterbaren) Wrapper von Microsoft.
Beispielsweise:
#include <msclr\marshal_cppstd.h>
System::String^ managed = "test";
std::string unmanaged = msclr::interop::marshal_as<std::string>(managed);
Sie können dies einfach wie folgt tun
#include <msclr/marshal_cppstd.h>
System::String^ xyz="Hi boys";
std::string converted_xyz=msclr::interop::marshal_as< std::string >( xyz);
Das hat bei mir funktioniert:
#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;
Hier sind einige Konvertierungsroutinen, die ich vor vielen Jahren für ein c ++ / cli-Projekt geschrieben habe. Sie sollten trotzdem funktionieren.
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;
}
Ich habe eine einfache Möglichkeit gefunden, einen std :: string aus einem String ^ zu erhalten, indem ich sprintf () verwende.
char cStr[50] = { 0 };
String^ clrString = "Hello";
if (clrString->Length < sizeof(cStr))
sprintf(cStr, "%s", clrString);
std::string stlString(cStr);
Sie müssen die Marschallfunktionen nicht aufrufen!
UPDATE Dank Eric habe ich den Beispielcode geändert, um die Größe der Eingabezeichenfolge zu überprüfen und einen Pufferüberlauf zu verhindern.
Ich habe stundenlang versucht, einen Windows Form Listbox ToString-Wert in eine Standardzeichenfolge zu konvertieren, damit ich ihn mit fstream zur Ausgabe in eine txt-Datei verwenden kann. Mein Visual Studio enthielt keine Marschall-Header-Dateien, die von mehreren Antworten verwendet wurden. Nach so viel Versuch und Irrtum fand ich endlich eine Lösung für das Problem, das nur System :: Runtime :: InteropServices verwendet:
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;
Und hier ist die MSDN-Seite mit dem Beispiel: http://msdn.microsoft.com/en-us/library/1b4az623(v=vs.80).aspx
Ich weiß, dass es eine ziemlich einfache Lösung ist, aber ich brauchte STUNDEN, um Fehler zu beheben und mehrere Foren zu besuchen, um endlich etwas zu finden, das funktioniert.
C # verwendet das UTF16-Format für seine Zeichenfolgen.
Neben der Konvertierung der Typen sollten Sie sich auch des tatsächlichen Formats der Zeichenfolge bewusst sein.
Beim Kompilieren für einen Multi-Byte-Zeichensatz setzt Visual Studio und die Win-API UTF8 voraus (eigentlich Windows- Codierung, Windows-28591 ).
Beim Kompilieren für den Unicode-Zeichensatz nehmen Visual Studio und die Win-API UTF16 an.
Sie müssen also die Zeichenfolge auch vom UTF16- in das UTF8-Format konvertieren und nicht nur in std :: string konvertieren.
Dies ist erforderlich, wenn Sie mit Formaten mit mehreren Zeichen wie einigen nicht-lateinischen Sprachen arbeiten.
Die Idee ist zu entscheiden, dass std::wstring
immer UTF16 repräsentiert .
Und repräsentiert std::string
immer UTF8 .
Dies wird vom Compiler nicht erzwungen, sondern ist eher eine gute Richtlinie.
#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;
}
Oder haben Sie es in einer kompakteren Syntax:
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;
}
// Ich habe VS2012 verwendet, um den folgenden Code zu schreiben: convert_system_string to 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;
}