gpt4 book ai didi

c++ - 传递参数(将 std::string 转换为 LPWSTR 的概率)

转载 作者:行者123 更新时间:2023-11-30 04:04:49 35 4
gpt4 key购买 nike

这有点烦人。我尝试将参数从 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”启动),消息框将正确提示:

enter image description here enter image description here

然而,我尝试从我的 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));
}

结果如下:

enter image description here

好的,尝试使用 startGame("This is a longer string!") 测试更长的字符串。你看,只有第一个词会被截断。我已经尝试了 30 多分钟来解决这个问题:

enter image description here

你能告诉我,我做错了什么吗?我已经尝试了很多转换示例来将 std::string 转换为 LPWSTR 但没有任何效果。其他方法给了我像汉字这样的神秘输出。

最佳答案

  1. MessageBox 函数接受两个正确输入为 LPCTSTR 的参数。假设 unicode 等于 LPCWSTRwchar_t const *
  2. 在 unicode 下,您根本不应该1 使用 std::string。它基于 char,您到处都需要基于 wchar_t 的字符串。
  3. std::wstring 基于 wchar_t,因此您想使用它。
  4. 由于参数是正确的 const,MessageBox 将接受 std::wstring::c_str() 的结果而不进行转换。

请注意,您代码中的许多转换都是不必要的。让我们开始:

/* convert/cast LPTSTR to LPCWSTR */
LPCWSTR test = (LPCWSTR) lpCmdLine;

LPCWSTRwchar_t const * 如果你设置了 unicode(就像你看起来那样),LCTSTRwchar_t *。添加 const 是 C++ 中的隐式转换。所以

test = lpCmdLine;

会做同样的事情。没有选择 unicode 的错误风险,在这种情况下 LCTSTR 扩展为 char * 并且语句将失败并出现“无法转换为不兼容的指针类型”错误。通过强制转换,它可以编译,但由于 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()宏生成) , 所以我希望它返回一个 narrow 字符串(你似乎没有显示那个签名,所以我不确定)。现在你盲目地把它转换到宽,这会产生垃圾,它不应该能够启动这个过程。另一方面,只要字符串仅为 ASCII,参数的转换实际上似乎是正确的。

1对于可移植程序,wchar_t 仍然是一团糟,因为它在某些平台上是 4 个字节,而在其他平台上是 2 个字节(包括急切创建宽的窗口)当 2 个字节足够时所有接口(interface)的版本,当 Unicode 超过它时卡在 2 个字节)。至少对于输入和输出,您通常需要特定的编码,通常是 Utf-8(因为它向后兼容 ASCII,但 Windows 不支持它)。很多人,包括我,在编写可移植程序时只是准备转换函数以在某处调用系统接口(interface)并在 Utf-8(例如 Gtk)或 Utf-16(存储在 uint16_t,而不是 wchar_t,就像 Qt 或 ICU 一样)在内部。

关于c++ - 传递参数(将 std::string 转换为 LPWSTR 的概率),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23591748/

35 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com