有人可以发布一个可以转换的简单代码,
System::String^
到,
C++std::string
即,我只想分配的值,
String^ originalString;
到,
std::string newString;
有人可以发布一个可以转换的简单代码,
System::String^
到,
C++std::string
即,我只想分配的值,
String^ originalString;
到,
std::string newString;
不要自己动手,使用Microsoft 提供的这些方便(且可扩展)的包装器。
例如:
#include <msclr\marshal_cppstd.h>
System::String^ managed = "test";
std::string unmanaged = msclr::interop::marshal_as<std::string>(managed);
您可以按如下方式轻松执行此操作
#include <msclr/marshal_cppstd.h>
System::String^ xyz="Hi boys";
std::string converted_xyz=msclr::interop::marshal_as< std::string >( xyz);
看看System::Runtime::InteropServices::Marshal::StringToCoTaskMemUni()
和它的朋友。
抱歉现在无法发布代码;我在这台机器上没有 VS 在发布前检查它是否编译。
这对我有用:
#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;
这是我多年前为一个 c++/cli 项目编写的一些转换例程,它们应该仍然可以工作。
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;
}
我花了几个小时试图将 Windows 表单列表框的 ToString 值转换为标准字符串,以便我可以将它与 fstream 一起使用以输出到 txt 文件。我的 Visual Studio 没有附带我发现的几个答案说要使用的编组头文件。经过这么多的试验和错误,我终于找到了解决问题的方法,只使用 System::Runtime::InteropServices:
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;
这是带有示例的 MSDN 页面:http: //msdn.microsoft.com/en-us/library/1b4az623 (v=vs.80).aspx
我知道这是一个非常简单的解决方案,但这花了我几个小时的故障排除并访问了几个论坛,最终找到了可行的方法。
我发现从 String^ 获取 std::string 的简单方法是使用 sprintf()。
char cStr[50] = { 0 };
String^ clrString = "Hello";
if (clrString->Length < sizeof(cStr))
sprintf(cStr, "%s", clrString);
std::string stlString(cStr);
无需调用 Marshal 函数!
更新感谢 Eric,我修改了示例代码以检查输入字符串的大小,以防止缓冲区溢出。
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 <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;
}
或者使用更紧凑的语法:
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;
}
我喜欢远离编组器。
Using CString newString(originalString);
对我来说似乎更干净,更快。无需担心创建和删除上下文。
// 我用VS2012写了下面的代码-- 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;
}