ใครช่วยโพสต์รหัสง่ายๆที่จะแปลง
System::String^
ถึง,
C ++ std::string
คือฉันแค่ต้องการกำหนดค่าของ
String^ originalString;
ถึง,
std::string newString;
ใครช่วยโพสต์รหัสง่ายๆที่จะแปลง
System::String^
ถึง,
C ++ std::string
คือฉันแค่ต้องการกำหนดค่าของ
String^ originalString;
ถึง,
std::string newString;
คำตอบ:
เช็คเอาท์ System::Runtime::InteropServices::Marshal::StringToCoTaskMemUni()
และเพื่อน ๆ
ขออภัยไม่สามารถโพสต์รหัสได้ในขณะนี้ ฉันไม่มี VS ในเครื่องนี้เพื่อตรวจสอบคอมไพล์ก่อนโพสต์
อย่าม้วนของคุณเองใช้สิ่งเหล่านี้มีประโยชน์ (และขยาย) ห่อให้โดยไมโครซอฟท์
ตัวอย่างเช่น:
#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);
สิ่งนี้ใช้ได้ผลสำหรับฉัน:
#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;
}
ฉันใช้เวลาหลายชั่วโมงในการพยายามแปลงค่า ToString จาก listbox ของ windows เป็นสตริงมาตรฐานเพื่อที่ฉันจะได้ใช้กับ 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
ฉันรู้ว่ามันเป็นวิธีแก้ปัญหาที่ค่อนข้างง่าย แต่ต้องใช้เวลาหลายชั่วโมงในการแก้ไขปัญหาและไปที่ฟอรัมต่างๆเพื่อค้นหาสิ่งที่ใช้งานได้ในที่สุด
ฉันพบวิธีง่ายๆในการรับ std :: string จาก String ^ คือการใช้ sprintf ()
char cStr[50] = { 0 };
String^ clrString = "Hello";
if (clrString->Length < sizeof(cStr))
sprintf(cStr, "%s", clrString);
std::string stlString(cStr);
ไม่ต้องเรียกฟังก์ชั่นจอมพล!
อัปเดตขอบคุณ Eric ฉันได้แก้ไขโค้ดตัวอย่างเพื่อตรวจสอบขนาดของสตริงอินพุตเพื่อป้องกันไม่ให้บัฟเฟอร์ล้น
C # ใช้รูปแบบ UTF16 สำหรับสตริง
ดังนั้นนอกจากการแปลงประเภทแล้วคุณควรคำนึงถึงรูปแบบจริงของสตริงด้วย
เมื่อคอมไพล์สำหรับ ชุดอักขระแบบหลายไบต์ Visual Studio และ Win API จะถือว่า UTF8 (การเข้ารหัส Windows ที่แท้จริงคือWindows-28591 )
เมื่อคอมไพล์สำหรับUnicode Character set 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 เป็น 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;
}