我有一个System::String^C++代码变量.应将此变量转换std::string为稍后转换为const char*via的变量c_str.
// original string
System::String^ path = ...;
// convert to std::string
msclr::interop::marshal_context context;
std::string filename(context.marshal_as<std::string>(path));
// call API function that internally connects to sqlite3 using sqlite3_open as
// sqlite3_open(filename.c_str())
// https://www.sqlite.org/c3ref/open.html -
// const char *filename, /* Database filename (UTF-8) */
doCalculation(filename)
Run Code Online (Sandbox Code Playgroud)
它适用于ASCII路径,但如果路径包含非拉丁字符,则会失败.
所以我需要将marshalled std :: string从当前实现(ASCII?)转换为UTF8.
我试过了
std::wstring dbPath(context.marshal_as<std::wstring>(path));
std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>, wchar_t> convert;
std::string dbPathU8 = convert.to_bytes(dbPath);
Run Code Online (Sandbox Code Playgroud)
但它不起作用.
你想要做的是使用.Net方法直接转换为UTF-8.
Encoding类中的可用方法并不是您正在寻找的(从托管String直接到非托管字符串或字节数组),因此我们需要一个中介和一些手动复制.
String^ path = ...;
// First, convert to a managed array of the bytes you want.
array<Byte>^ bytes = Encoding::UTF8->GetBytes(path);
// Then, copy those bytes from the managed byte array to an unmanaged string.
std::string str;
str.resize(bytes->Length);
Marshal::Copy(bytes, 0, IntPtr(str.data()), bytes->Length);
// OR, copy directly to the char* you want eventually.
char* chars = new char[bytes->Length + 1]; // or malloc(), or whatever.
Marshal::Copy(bytes, 0, IntPtr(chars), bytes->Length);
chars[bytes->Length] = '\0'; // null terminate.
// don't forget to free the buffer when you're done with it!
Run Code Online (Sandbox Code Playgroud)
有几种GetBytes可用的变体,但它们的参数似乎既可以管理,也可以不受管理.(String^和array^,或char*和byte*,但不是字符串^和字节*).因此,我们有编码类创建一个管理字节数组,然后我们使用Marshal::Copy方法的那些字节复制无论对非托管字符串对象,或者直接连接到一个char*.
| 归档时间: |
|
| 查看次数: |
2004 次 |
| 最近记录: |