C++ .NET で System::String を std::string に変換するにはどうすればよいですか?
6 に答える
最近のバージョンの .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 記事があります
また、C++/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;
}
C# は、文字列に UTF16 形式を使用します。
したがって、型を変換するだけでなく、文字列の実際の形式についても意識する必要があります。
マルチバイト文字セット用にコンパイルする場合、Visual Studio と Win API は UTF8 (実際にはWindows-28591である Windows エンコーディング) を前提としています。Unicode 文字セット
用にコンパイルする場合、Visual Studio と Win API は UTF16 を想定しています。
そのため、文字列を std::string に変換するだけでなく、UTF16 から UTF8 形式にも変換する必要があります。
これは、一部の非ラテン言語のような複数文字形式で作業する場合に必要になります。
アイデアは、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;
}
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;
}
上記の回答で表示されるあいまいなエラーが多すぎました (はい、私は C++ 初心者です)。
これは、C#からC ++ CLIに文字列を送信するために私にとってはうまくいきました
C#
bool result;
result = mps.Import(mpsToolName);
C++ 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;
}
使用できる Windows ランタイム コンポーネントの作成:
String^ systemString = "Hello";
std::wstring ws1(systemString ->Data());
std::string standardString(ws1.begin(), ws1.end());