QCoreApplication
。由于某些原因,我需要使用
CommandLineToArgvW
获取参数列表,如下所示:LPWSTR * argvW = CommandLineToArgvW( GetCommandLineW(), &argc );
我了解在现代Windows操作系统上,
LPWSTR
实际上是wchar_t*
,它是16位并使用UTF-16编码。但如果我想初始化
QCoreApplication
,只能使用char*
而不能使用wchar_t *
。 QCoreApplication
那么问题来了:如何安全地将CommandLineToArgvW()
函数返回的LPWSTR
转换为char*
,同时不丢失UNICODE编码(例如,汉字仍然是汉字)?我尝试了许多不同的方法都没有成功:
1:
std::string const argvString = boost::locale::conv::utf_to_utf<char>( argvW[0] )
2:
int res;
char buf[0x400];
char* pbuf = buf;
boost::shared_ptr<char[]> shared_pbuf;
res = WideCharToMultiByte(CP_UTF8, 0, pcs, -1, buf, sizeof(buf), NULL, NULL);
3:首先将其转换为QString,然后再转换为UTF-8。
ETID:
问题已解决。对于这三种方法,UTF-16宽字符到UTF-8 char
的转换实际上都可以正常工作,没有问题。在Visual Studio中,为了正确查看调试中的UTF-8字符串,需要在所监视的变量名后面添加s8
格式说明符(参见:https://msdn.microsoft.com/en-us/library/75w45ekt.aspx)。这是我忽略的部分,让我认为我的字符串转换有问题。
实际上,这里的真正问题是当调用QCoreApplication.arguments()
时,返回的QString
是由QString::fromLocal8Bit()
构造的,当命令行参数包含Unicode字符时,会引发编码问题。解决方法是,在Windows上每次需要检索命令行参数时,总是调用Windows APICommandLineToArgvW()
,并将16位的UTF-16 wchar_t *(或LPWSTR)转换为8位的UTF-8 char *(通过上述三种方法之一)。
CommandLineToArgvW
,除非您将修改后的参数传递给QCoreApplication
构造函数。它没有说明什么是“修改后的”,但大概意思是对于普通代码只是盲目地转发main
参数,但如果有任何差异,则遵循客户端代码的意愿。请参见http://doc.qt.io/qt-5/qcoreapplication.html#arguments。 - Cheers and hth. - AlfCommandLineToArgvW
来处理Win32的问题,你发现得很好。经过更仔细的阅读后,看起来Qt会将参数转换为本地的8位字符集,无论如何。你可以将修改后的参数传递给构造函数,但它们必须是系统本地编码。我对为什么会这样感到有些惊讶,尽管我怀疑这是出于历史原因。QGuiApplication
可能会修改这种行为并读取Unicode字符串,但是在QPA的混乱中导航似乎是不可攻破的。我已经删除了我的答案,因为它没有帮助。 - jonspaceharper