Wie konvertiert man System :: String zu std :: string in C++ .NET?C++ .NET konvertieren System :: String in std :: string
Antwort
Es ist saubere Syntax, wenn Sie eine aktuelle Version von .NET sind
#include "stdafx.h"
#include <string>
#include <msclr\marshal_cppstd.h>
using namespace System;
int main(array<System::String ^> ^args)
{
System::String^ managedString = "test";
msclr::interop::marshal_context context;
std::string standardString = context.marshal_as<std::string>(managedString);
return 0;
}
Dies gibt Ihnen auch besser clean-up im Gesicht von Ausnahmen.
Es gibt eine msdn article für verschiedene andere Umwandlungen
Wird dabei auch die Codierung von UTF-16 (.Net-Standard) nach UTF-8 (Std :: String) beachtet? – zak
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;
}
Dies ist die ältere Syntax. Ich bevorzuge den, den Colin oben vorgeschlagen hat. – orad
Was passiert, wenn sstr() wirft? Würde das nicht dazu führen, dass cstr zu einem Leck wird? –
Und als Reaktion auf den „einfacheren Weg“ in späteren Versionen von C++/CLI, können Sie es ohne den marshal_context zu tun. Ich weiß, das funktioniert in Visual Studio 2010; vorher nicht sicher.
#include "stdafx.h"
#include <string>
#include <msclr\marshal_cppstd.h>
using namespace msclr::interop;
int main(array<System::String ^> ^args)
{
System::String^ managedString = "test";
std::string standardString = marshal_as<std::string>(managedString);
return 0;
}
Sehen Sie sich den MSDN-Artikel Collin an, um zu sehen, wann marschall_as zu verwenden ist und wann marschall_kontext verwendet werden soll. Im Allgemeinen wird der Marshal_context benötigt, wenn nicht gemanagte Ressourcen bereinigt werden müssen. – rotti2
Der Artikel sagt, dass man nur einen Kontext benötigt, wenn der native Typ keinen Destruktor hat, um seine eigene Bereinigung durchzuführen. Also, im Falle von 'std :: string', wird das benötigt? –
Der Kontext wird nicht für 'std :: string' benötigt. Der Kontext wird nur benötigt, wenn von einem umhüllten Typ zu einem unverpackten Typ (d. H. Roher Zeiger) marshaliert wird. Wie in [Überblick über Marshalling in C++] (http://msdn.microsoft.com/en-us/library/bb384865.aspx) aufgeführt, gibt es nur drei Instanzen, in denen der Kontext benötigt wird. –
Ich hatte zu viele mehrdeutige Fehler mit den oben genannten Antworten zeigt sich (ja, ich bin ein C++ Noob)
Das ist für mich gearbeitet Zeichenfolge von C# C für das Senden ++ CLI
C#
bool result;
result = mps.Import(mpsToolName);
C++ CLI
Funktion:
bool ManagedMPS::Import(System::String^ mpsToolNameTest)
std::string mpsToolName;
mpsToolName = toStandardString(mpsToolNameTest);
Funktion, die aus der Umwandlung String^arbeitet std :: string
static std::string toStandardString(System::String^ string)
{
using System::Runtime::InteropServices::Marshal;
System::IntPtr pointer = Marshal::StringToHGlobalAnsi(string);
char* charPointer = reinterpret_cast<char*>(pointer.ToPointer());
std::string returnString(charPointer, string->Length);
Marshal::FreeHGlobal(pointer);
return returnString;
}
AUF WEITERE RESEARCH, es scheint, dass diese sauberer und sicherer ist.
Ich wechselte zu dieser Methode stattdessen.
std::string Utils::ToUnmanagedString(String^ stringIncoming)
{
std::string unmanagedString = marshal_as<std::string>(stringIncoming);
return unmanagedString;
}
Wie haben Sie es geschafft, alle IServiceProvider-Mehrdeutigkeitsfehler zu beseitigen? –
Ich erinnere mich nicht, diese Fehler zu bekommen. Ich war neu in C++, jetzt bin ich auf einem anderen Vertrag/Projekt mit einer anderen Firma .... Entschuldigung, viel Glück. –
eine Windows-Runtime-Komponente Erstellen Sie verwenden können:
String^ systemString = "Hello";
std::wstring ws1(systemString ->Data());
std::string standardString(ws1.begin(), ws1.end());
C# verwendet das UTF16-Format für die Saiten.
Neben der Konvertierung der Typen sollten Sie sich also auch des tatsächlichen Formats der Zeichenfolge bewusst sein.
Beim Kompilieren für Multi-Byte-Zeichensatz Visual Studio und die Win-API nimmt UTF8 (eigentlich Windows-Codierung, die Windows-28591 ist).
Beim Kompilieren für Unicode-Zeichensatz Visual Studio und die Win-API nehmen UTF16 an.
Also müssen Sie die Zeichenfolge von UTF16 in UTF8 Format konvertieren, und nicht nur in std :: string konvertieren.
Dies wird notwendig, wenn Sie mit Multi-Character-Formaten wie einigen nicht-lateinischen Sprachen arbeiten.
Die Idee ist, zu entscheiden, dass std::wstring
immerUTF16 darstellt.
Und std::string
immer steht für UTF8.
Dies wird nicht vom Compiler erzwungen, es ist mehr eine gute Richtlinie zu haben.
#include "stdafx.h"
#include <string>
#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 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;
}
Nicht. In std :: wstring konvertieren. System.String ist Unicode, nicht ASCII – MSalters
@MSalters Huh? Sie scheinen den Eindruck zu haben, dass die Konvertierung keine Übersetzung enthält oder dass jeder immer auswählen kann, mit welchen APIs er interagieren wird ... –