Каков утвержденный способ преобразования из char* в System::string и обратно в C++/CLI? Я нашел несколько ссылок на шаблонные функции marshal_to‹> в Google, но, похоже, эта функция никогда не использовалась для Visual Studio 2005 (и, насколько мне известно, ее нет и в Visual Studio 2008). Я также видел некоторый код в блоге Стэна Липпмана, но это с 2004 года. Я также видел Marshal::StringToHGlobalAnsi(). Есть ли метод, который считается «наилучшей практикой»?
Каков наилучший способ преобразования между char* и System::String в C++/CLI
Ответы (5)
Здесь есть хороший обзор (эта поддержка маршалинга добавлена для VS2008): http://www.codeproject.com/KB/mcpp/OrcasMarshalAs.aspx
#include <msclr\marshal.h> // marshal_context context; // my_c_string = context.marshal_as<const char*>(my_csharp_string);
- person gatopeich; 08.10.2012
msclr::interop::marshal_context
- person Mugen; 21.02.2018
System::String имеет конструктор, который принимает char*:
using namespace system;
const char* charstr = "Hello, world!";
String^ clistr = gcnew String(charstr);
Console::WriteLine(clistr);
Вернуть char* немного сложнее, но не так уж плохо:
IntPtr p = Marshal::StringToHGlobalAnsi(clistr);
char *pNewCharStr = static_cast<char*>(p.ToPointer());
cout << pNewCharStr << endl;
Marshal::FreeHGlobal(p);
Marshal::StringToHGlobalAnsi
— плохой вариант по сравнению с marshal_context
(как упоминал Мэтью), который использует RAII для автоматического освобождения буфера. Не говоря уже о том, что имя совершенно неправильное, оно вообще не возвращает HGLOBAL
.
- person Ben Voigt; 19.02.2012
gcnew
использовать строку с char *
строкой в качестве аргумента. Может быть, вы можете использовать signed char *
?
- person Ben Straub; 15.11.2018
Что мы сделали, так это создали объект C++\CLI, который содержал строку в неуправляемом коде и выдавал управляемые копии элемента. Код конверсии очень похож на тот, что есть в блоге Стэна (я точно не помню) (если вы используете его код, убедитесь, что вы обновили его, чтобы использовать delete[]), но мы позаботились о том, чтобы деструктор справился с освобождением всех неуправляемые элементы объекта. Это немного преувеличено, но у нас не было утечек, когда мы связывались с устаревшими модулями кода C++.
Я создал несколько вспомогательных методов. Мне нужно было сделать это, чтобы перейти от старой библиотеки Qt к CLI String. Если кто-нибудь может добавить к этому и сказать мне, похоже ли, что у меня есть утечка памяти и что я могу сделать, чтобы это исправить, я был бы очень признателен.
void MarshalString ( String ^ s, wstring& os ) {
using namespace Runtime::InteropServices;
const wchar_t* char = (const wchar_t*)(Marshal::StringToHGlobalUni(s)).ToPointer();
os = char;
}
QString SystemStringToQt( System::String^ str)
{
wstring t;
MarshalString(str, t);
QString r = QString::fromUcs2((const ushort*)t.c_str());
return r;
}
Одна дополнительная ссылка на сводку возможных способов:
http://support.microsoft.com/?kbid=311259