10 ответов:
проверить
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; }
Я потратил несколько часов, пытаясь преобразовать значение Windows form listbox ToString в стандартную строку, чтобы я мог использовать ее с fstream для вывода в txt-файл. В моей Visual Studio не было файлов заголовков marshal, которые я нашел в нескольких ответах. После стольких проб и ошибок я наконец нашел решение проблемы, которая просто использует 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 из строки^ - это использовать sprintf ().
char cStr[50] = { 0 }; String^ clrString = "Hello"; if (clrString->Length < sizeof(cStr)) sprintf(cStr, "%s", clrString); std::string stlString(cStr);нет необходимости вызывать функции Маршала!
обновление благодаря Эрику, я изменил пример кода, чтобы проверить размер входной строки, чтобы предотвратить переполнение буфера.
C# использует формат UTF16 для своих строк.
Таким образом, помимо простого преобразования типов, вы также должны знать о фактическом формате строки.при компиляции для Многобайтовый набор символов Visual Studio и Win API предполагает UTF8 (на самом деле кодировка windows, которая Windows-28591).
При компиляции для набор символов Unicode Visual studio и Win API предполагают UTF16.Итак, вы должны преобразуйте строку из формата UTF16 в формат UTF8, а не просто преобразуйте в std::string.
Это становится необходимым при работе с multi-символьные форматы, как некоторые не-латинских языков.идея в том, чтобы решить, что
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; }
Comments