如何在 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 编码,即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;
}
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++ 命令行
功能:
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());