Как вы конвертируете System:: String в std::string в С++.NET?
С++.NET преобразует System:: String в std::string
Ответ 1
Синтаксис более чистый, если вы используете последнюю версию .net
#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;
}
Это также дает вам лучшую очистку перед исключениями.
msdn article для различных других преобразований
Ответ 2
И в ответ на "более простой способ" в более поздних версиях С++/CLI вы можете сделать это без marshal_context. Я знаю, что это работает в Visual Studio 2010; не уверен до этого.
#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;
}
Ответ 3
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;
}
Ответ 4
С# использует формат UTF16 для своих строк.
Таким образом, помимо преобразования типов, вы также должны быть осведомлены о фактическом формате строки.
При компиляции для многобайтового набора символов Visual Studio и Win API предполагают UTF8 (на самом деле кодировка Windows Windows-28591). При компиляции для набора символов Unicode Visual Studio и Win API предполагают UTF16.
Итак, вы должны преобразовать строку из UTF16 в формат UTF8, а не просто конвертировать в std::string.
Это станет необходимым при работе с многосимвольными форматами, такими как некоторые нелатинские языки.
Идея состоит в том, чтобы решить, что std::wstring
всегда представляет UTF16.
И std::string
всегда представляет UTF8.
Это не выполняется компилятором, это скорее хорошая политика.
#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;
}
Или используйте более компактный синтаксис:
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;
}
Ответ 5
У меня было слишком много неоднозначных ошибок, появившихся с приведенными выше ответами (да, я - С++ noob)
Это сработало для меня для отправки строки из С# в С++ CLI
С#
bool result;
result = mps.Import(mpsToolName);
С++ CLI
функция:
bool ManagedMPS::Import(System::String^ mpsToolNameTest)
std::string mpsToolName;
mpsToolName = toStandardString(mpsToolNameTest);
которая работает от преобразования String ^ в 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;
}
В ДАЛЬНЕЙШЕМ ИССЛЕДОВАНИИ, кажется, что это чище и безопаснее.
Вместо этого я переключился на этот метод.
std::string Utils::ToUnmanagedString(String^ stringIncoming)
{
std::string unmanagedString = marshal_as<std::string>(stringIncoming);
return unmanagedString;
}
Ответ 6
Создание компонента времени выполнения Windows, который вы можете использовать:
String^ systemString = "Hello";
std::wstring ws1(systemString ->Data());
std::string standardString(ws1.begin(), ws1.end());