Bisakah seseorang mengeposkan kode sederhana yang akan mengubah,
System::String^
Untuk,
C ++ std::string
Yaitu, saya hanya ingin memberikan nilai,
String^ originalString;
Untuk,
std::string newString;
Bisakah seseorang mengeposkan kode sederhana yang akan mengubah,
System::String^
Untuk,
C ++ std::string
Yaitu, saya hanya ingin memberikan nilai,
String^ originalString;
Untuk,
std::string newString;
Jawaban:
Jangan roll Anda sendiri, gunakan ini berguna (dan extensible) bungkus yang disediakan oleh Microsoft.
Sebagai contoh:
#include <msclr\marshal_cppstd.h>
System::String^ managed = "test";
std::string unmanaged = msclr::interop::marshal_as<std::string>(managed);
Anda dapat dengan mudah melakukan ini sebagai berikut
#include <msclr/marshal_cppstd.h>
System::String^ xyz="Hi boys";
std::string converted_xyz=msclr::interop::marshal_as< std::string >( xyz);
Ini berhasil untuk saya:
#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;
Berikut adalah beberapa rutinitas konversi yang saya tulis bertahun-tahun yang lalu untuk proyek c ++ / cli, mereka masih harus berfungsi.
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;
}
Saya menghabiskan berjam-jam mencoba untuk mengubah nilai ToString listbox windows form menjadi string standar sehingga saya dapat menggunakannya dengan fstream untuk menghasilkan output ke file txt. Visual Studio saya tidak datang dengan file header marshal yang menurut beberapa jawaban saya gunakan. Setelah begitu banyak trial and error akhirnya saya menemukan solusi untuk masalah yang hanya menggunakan 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;
Dan berikut adalah halaman MSDN dengan contoh: http://msdn.microsoft.com/en-us/library/1b4az623(v=vs.80).aspx
Saya tahu ini adalah solusi yang cukup sederhana tetapi ini membutuhkan waktu berjam-jam untuk memecahkan masalah dan mengunjungi beberapa forum untuk akhirnya menemukan sesuatu yang berfungsi.
Saya menemukan cara mudah untuk mendapatkan std :: string dari String ^ adalah dengan menggunakan sprintf ().
char cStr[50] = { 0 };
String^ clrString = "Hello";
if (clrString->Length < sizeof(cStr))
sprintf(cStr, "%s", clrString);
std::string stlString(cStr);
Tidak perlu memanggil fungsi Marsekal!
UPDATE Terima kasih kepada Eric, saya telah memodifikasi kode sampel untuk memeriksa ukuran string input untuk mencegah buffer overflow.
C # menggunakan format UTF16 untuk stringnya.
Jadi, selain hanya mengonversi tipe, Anda juga harus sadar tentang format string sebenarnya.
Ketika mengkompilasi untuk kumpulan Karakter Multi-byte Visual Studio dan Win API mengasumsikan UTF8 (Sebenarnya pengkodean windows yang Windows-28591 ).
Saat menyusun untuk kumpulan Karakter Unicode Visual studio dan Win API mengasumsikan UTF16.
Jadi, Anda juga harus mengonversi string dari format UTF16 ke UTF8, dan tidak hanya mengonversi ke std :: string.
Ini akan menjadi penting saat bekerja dengan format multi-karakter seperti beberapa bahasa non-latin.
Idenya adalah untuk memutuskan bahwa std::wstring
selalu mewakili UTF16 .
Dan std::string
selalu mewakili UTF8 .
Ini tidak diberlakukan oleh kompilator, ini lebih merupakan kebijakan yang baik untuk dimiliki.
#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;
}
Atau miliki dalam sintaks yang lebih ringkas:
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;
}
// Saya menggunakan VS2012 untuk menulis kode di bawah ini-- convert_system_string ke 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;
}