NPAPI
插件传递给EXE。
第一条信息:可执行文件目前是占位符,只打印出传递的参数作为消息框:
int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow) {
/* Print out the arguments */
MessageBox(NULL, lpCmdLine, TEXT("World of RPG"), NULL);
/* Exit with return code 0x00 */
return 0;
}
当我尝试通过Visual Studio启动应用程序时(以参数" -console"启动),将正确提示消息框:
然而,我尝试从我的NPAPI
插件执行可执行文件:
/* Javascript call: document.getElementById("myPlugin").startGame("-console"); */
std::string WoRPGAPI::startGame(const std::string& method_args) {
/* Define JSON result variables */
FB::VariantMap json;
Json::StyledWriter writer;
/* Define process variables*/
PROCESS_INFORMATION processInformation = { 0 };
STARTUPINFO startupInfo = { 0 };
startupInfo.cb = sizeof(startupInfo);
LPWSTR game_exe = LgetGamePath("World of RPG.exe").c_str(); // example: "C:\\Program Files (x86)\\World of RPG\\World of RPG.exe"
LPWSTR game_args = method_args.c_str(); // example: "-console"
/* Create the Process */
BOOL status = CreateProcess(game_exe, game_args, NULL, NULL, FALSE, 0, NULL, NULL, &startupInfo, &processInformation);
/* Check the process status */
if (!status) {
DWORD dLastError = GetLastError();
LPCTSTR strErrorMessage = NULL;
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_ARGUMENT_ARRAY | FORMAT_MESSAGE_ALLOCATE_BUFFER, NULL, dLastError, 0, (LPWSTR)&strErrorMessage, 0, NULL);
json["code"] = dLastError;
json["message"] = strErrorMessage;
}
json["status"] = status;
/* get JSON back to the browser */
return writer.write(FB::variantToJsonValue(json));
}
结果如下:
好的,尝试使用startGame("This is a longer string!")
的较长字符串进行测试。你看,只有第一个单词会被切断。我已经尝试了30多分钟来解决这个问题:
你能告诉我,我做错了什么吗?
我尝试过很多转化示例,将std::string
转换为LPWSTR
但没有任何效果。其他方法给了我像中文字符的密码输出。
答案 0 :(得分:2)
MessageBox
函数将两个参数正确输入为LPCTSTR
。假设unicode等于LPCWSTR
或wchar_t const *
。std::string
一起工作。它基于char
,您将需要基于wchar_t
的字符串。std::wstring
基于wchar_t
,因此您想要使用它。MessageBox
将接受std::wstring::c_str()
的结果而不进行投射。请注意,代码中的许多强制转换都是不必要的。让我们从:
开始/* convert/cast LPTSTR to LPCWSTR */
LPCWSTR test = (LPCWSTR) lpCmdLine;
LPCWSTR
为wchar_t const *
,如果您设置了unicode(正如您所见),则LCTSTR
为wchar_t *
。在C ++中添加const
是隐式转换。所以
test = lpCmdLine;
也会这样做。通过不选择unicode而不会冒错误,在这种情况下LCTSTR
会扩展为char *
并且语句将失败并且#34;无法转换为不兼容的指针类型"错误。使用强制转换编译,但由于C风格的强制转换会进行重新解释转换,即将内存内容视为请求的类型,结果是垃圾。
现在我不明白的是:
BOOL status = CreateProcess((LPWSTR) LgetGamePath("World of RPG.exe").c_str(), game_args, NULL, NULL, FALSE, 0, NULL, NULL, &startupInfo, &processInformation);
函数LgetGamePath
得到一个窄字符串(宽文字有L
前缀,也可以使用TEXT()
宏生成),所以我希望它返回一个狭窄的字符串(你似乎没有显示签名,所以我不确定)。现在你盲目地把它扔到宽处,这将产生垃圾,它不应该能够启动这个过程。另一方面,参数的转换实际上似乎是正确的,只要字符串只是ASCII。
1 对于可移植程序wchar_t
仍然是一团糟,因为它在某些平台上是4个字节而在其他平台上是2个字节(包括急切地创建所有平台版本的窗口)当2个字节足够时接口,当Unicode超过它时被卡住2个字节)。至少对于输入和输出,您通常需要特定的编码,通常是Utf-8(由于它与ASCII的向后兼容性,但Windows不支持它)。在编写可移植程序时,包括我在内的很多人只是准备转换函数来调用系统接口,并在Utf-8(例如Gtk)或Utf-16(存储在uint16_t
中,而不是wchar_t
中工作。 ,内部也是Qt或ICU。