C++ 如何将lua_tostring()中的值赋给utf-8中wstring或const wchar_t*类型的变量

C++ 如何将lua_tostring()中的值赋给utf-8中wstring或const wchar_t*类型的变量,c++,winapi,unicode,lua,C++,Winapi,Unicode,Lua,函数lua_tostring的返回值类型为const char*。但是,我有一个C函数,它需要一个字符串作为参数。字符串将是UTF-8编码格式的中文 外部C LUALIB_API int PrintStringlua_状态*L{ const char*str=lua\u tostringL,1//获取字符串参数 //字符串实际上是Lua中的utf-8。 常量WCHAR*str_w=…/*以某种方式使str成为常量WCHAR**/ SomeFuncNeedWCHARstr\u w//假设此函数需要

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

外部C LUALIB_API int PrintStringlua_状态*L{ const char*str=lua\u tostringL,1//获取字符串参数 //字符串实际上是Lua中的utf-8。 常量WCHAR*str_w=…/*以某种方式使str成为常量WCHAR**/ SomeFuncNeedWCHARstr\u w//假设此函数需要常量WCHAR*作为参数。 返回0; } 我尝试过使用MultiByteToWideChar

但是我猜str实际上将字符存储在UTF-8中,在这个转换之后,它将一个UTF-8转换为UTF-8。我是说,它转换了两次。所以我只想找到一种方法来解释从lua_tostring到const WCHAR*类型的返回值

您基本上可以认为SomeFuncNeedWCHAR具有一些类似的行为,比如MessageBoxExW,以UTF-8显示消息框

所以我想知道如何做到这一点。谢谢大家!

您没有正确使用MultiByteToWideChar

具体地说,在第一次调用时,您将其cchWideChar参数设置为-1,此时它需要改为0:

cchWideChar

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

即使它会成功,您也会过度分配缓冲区,严格来说这不是一个错误,但这是在浪费未使用的内存

请尝试以下方法:

外部C LUALIB_API int PrintStringlua_状态*L{ const char*str=lua_tostringL,1; int str_len=strlenstr+1;//避免MBTWC需要重新计算 //多次使用相同的字符串长度。还包括 //输出中的空终止符。。。 int w_len=MultiByteToWideCharCP_UTF8,0,str,str_len,NULL,0; WCHAR*str_w=新的WCHAR[w_len]; MultiByteToWideCharCP_UTF8,0,str,str_len,str_w,w_len; 一些功能需要更严格的要求; 删除[]str_w; 返回0; }
此转换后,它将utf-8转换为utf-8。-这是不可能的。MultiByteToWideChar从不转换为UTF-8。@EgorSkriptunoff我真的不明白这个函数是如何工作的。但是在文档上,它说这个函数将字符串映射为宽字符Unicode字符串。。不管怎样,这个函数并没有像我期望的那样工作。但基本上,我只想将lua_到string的字符串作为LPCWSTR.size*sizeofwchar__t类型中的一个参数传递,它应该是size,除了您的代码看起来正确之外,您能更清楚地解释一下您遇到了什么问题吗?@AlanBirtles谢谢。基本上,我只想将lua_tostring的返回值作为参数传递给MessageBoxExW。它需要一个LPCWSTR。我尝试使用MultiByteToWideChar将字符串转换为宽字符字符串。但是从lua_得到的字符串值实际上是lua中的utf-8格式。最后的结果是,通过MultiByteToWideChar转换后,消息框上出现了一些错误代码。所以我猜它可能会再转换一次不太确定?错误代码是什么?请给出一个肯定的答案!非常感谢。它最终完美地解决了我的问题。我以前认为cchWideChar在默认情况下应该传递-1,就像cbMultiByte一样。@YZS读取。cchWideChar根本不支持-1,只有>=0。@yzs cchWideChar描述输出缓冲区。API无法知道、计算或猜测其长度。它必须相信你。这与输入参数不同,比如cbMultiByte,API可以计算输入字符串的长度,前提是输入字符串以NUL结尾。
    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;