如何将 lua_tostring() 返回值赋值给一个 utf-8 编码的 wstring 或 const wchar_t* 类型变量?

lua_tostring() 函数返回值的类型是 const char*。 但是,我有一个 C 函数需要一个字符串作为参数。而且字符串是以 UTF-8 编码格式为中文。

extern "C" LUALIB_API int PrintString(lua_State * L) {
    const char* str = lua_tostring(L, 1) // 获取字符串参数
                                         // 而且字符串在 Lua 中实际上是以 UTF-8 格式的。

    const WCHAR* str_w = .../* 以某种方式使 str 成为 const WCHAR* */

    SomeFuncNeedWCHAR(str_w) // 假设这个函数需要一个 const WCHAR* 作为参数。

    return 0;
}

我已经尝试过使用 MultiByteToWideChar()

    int size = MultiByteToWideChar(CP_UTF8, 0, str, -1, NULL, -1);

    WCHAR* buffer = new wchar_t[size * sizeof(wchar_t)];
    MultiByteToWideChar(CP_UTF8, 0, str, -1, buffer, size * sizeof(wchar_t));

    SomeFuncNeedWCHAR(buffer)

    delete[] buffer;

但是,我猜测 str 实际上存储的是 UTF-8 字符,经过这个转换后,它将转换一个 UTF-8 到 UTF-8。(我是指,它转换了两次)。因此,我只想找到一种将 lua_tostring() 返回值解释为 const WCHAR* 类型的方法。

您可以将 SomeFuncNeedWCHAR() 看作类似于 MessageBoxExW() 的行为,显示一个以 UTF-8 格式的消息框。

因此,我想知道如何解决这个问题。 谢谢!

点赞
用户65863
用户65863

你没有正确使用MultiByteToWideChar()

具体而言,在第一个调用中,你将其cchWideChar参数设置为-1,而实际上应该是0

cchWideChar

指定由lpWideCharStr指向的缓冲区的大小(以字符为单位)。如果此值为 0,则函数返回所需的缓冲区大小(以字符为单位),包括任何终止空字符,并且不使用lpWideCharStr缓冲区。

即使它会成功,你也会过度分配buffer,这不是一个严格的错误,但是它浪费未使用的内存。

改用这个:

extern "C" LUALIB_API int PrintString(lua_State * L) {
    const char* str = lua_tostring(L, 1);

    int str_len = strlen(str) + 1; //避免多次重新计算字符串长度
                                   //同时在输出中包括空终止符...

    int w_len = MultiByteToWideChar(CP_UTF8, 0, str, str_len, NULL, 0);

    WCHAR* str_w = new WCHAR[w_len];
    MultiByteToWideChar(CP_UTF8, 0, str, str_len, str_w, w_len);

    SomeFuncNeedWCHAR(str_w);

    delete[] str_w;

    return 0;
}
2021-06-03 07:54:30