将WinMain(或wWinMain)的参数传递给普通的main函数

4
如果您试图从Console (/SUBSYSTEM:CONSOLE)更改构建类型为Windows (/SUBSYSTEM:WINDOWS),那么您将收到一个错误,报告入口点WinMain不存在: MSVCRT.lib(crtexew.obj) : error LNK2001: unresolved external symbol _WinMain@16 我认为解决这个问题的最佳方法是从WinMain调用您的正常int main(int, char**):
#ifdef _WINDOWS_
INT WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
    PSTR lpCmdLine, INT nCmdShow)
{
    return main(0, NULL);
}
#endif

问题在于ImageMagick正在使用控制台参数(我将来也打算使用它们):
所以传递NULL和0可能不是一个好主意。我该如何将WinMain参数转换为main参数?

1
您IP地址为143.198.54.68,由于运营成本限制,当前对于免费用户的使用频率限制为每个IP每72小时10次对话,如需解除限制,请点击左下角设置图标按钮(手机用户先点击左上角菜单按钮)。 - Some programmer dude
这将解决崩溃问题,但仍无法将真正的参数传递给我的函数。无论如何,谢谢。 - Tomáš Zato
@RSahu 我已经在打开的标签页中看到了这个。但它并没有真正回答这个问题 - 或者它回答了吗? - Tomáš Zato
1
它对我立即起作用了,但效果因人而异,没有特定的“正确”方法来做任何事情,只有适合你的方法才是正确的。祝好运。 - Retired Ninja
显示剩余3条评论
2个回答

7
一种方法是使用CommandLineToArgvW()函数解析GetCommandLineW()的结果,得到一个以UTF-16编码的argv风格的字符串数组,然后使用WideCharToMultiByte()函数将它们转换为ANSI字符串,以便将它们传递给main()函数(假设不能使用wmain()函数)。
例如:
int w_argc = 0;
LPWSTR* w_argv = CommandLineToArgvW(GetCommandLineW(), &w_argc);
if (w_argv)
{
    char** my_argv = new char*[w_argc];
    int my_argc = 0;

    for (int i = 0; i < w_argc; ++i)
    {
        int w_len = lstrlenW(w_argv[i]);
        int len = WideCharToMultiByte(CP_ACP, 0, w_argv[i], w_len, NULL, 0, NULL, NULL);
        my_argv[my_argc] = new char[len+1];
        WideCharToMultiByte(CP_ACP, 0, wargv[i], w_len, my_argv[my_argc], len+1, NULL, NULL);
        ++my_argc;
    }

    main(my_argc, my_argv);

    for (int i = 0; i < my_argc; ++i)
        delete[] my_argv[i];
    delete[] my_argv;

    LocalFree(w_argv);
}

或者:

int w_argc = 0;
LPWSTR* w_argv = CommandLineToArgvW(GetCommandLineW(), &w_argc);
if (w_argv)
{
    std vector<std::string> my_argv_buf;
    my_argv.reserve(w_argc);

    for (int i = 0; i < w_argc; ++i)
    {
        int w_len = lstrlenW(w_argv[i]);
        int len = WideCharToMultiByte(CP_ACP, 0, w_argv[i], w_len, NULL, 0, NULL, NULL);
        std::string s;
        s.resize(len);
        WideCharToMultiByte(CP_ACP, 0, wargv[i], w_len, &s[0], len, NULL, NULL);
        my_argv_buf.push_back(s);
    }

    std vector<char*> my_argv;
    my_argv.reserve(my_argv_buf.size());
    for (std vector<std::string>::iterator i = my_argv_buf.begin(); i != my_argv_buf.end(); ++i)
        my_argv.push_back(i->c_str());

    main(my_argv.size(), &my_argv[0]);

    LocalFree(w_argv);
}

我该如何使用WideCharToMultiByte()函数?整个过程看起来非常复杂... - Tomáš Zato

1
你可以使用CommandLineToArgvW函数将命令行解析和转换成C语言主函数所期望的格式。
 int argc;
 LPWSTR *argvw = CommandLineToArgvW(GetCommandLineW(), &argc);

 CallCMainFunction(argvw, argc);
 LocalFree(argvw);

请注意,这是宽字符格式,因为Windows本地期望utf-16命令行参数。如果InitializeMagick仅使用窄字符,则还必须进行转换(可以使用wcstombs_s完成,其中包含隐含的警告)。

标准的 main 函数定义为 int main(int, char**)。但是 LPWSTR* 不能转换成 char*(并且 &(LPWSTR*) 也不能变成 char**)。因此,我可能需要以某种方式进行转换... - Tomáš Zato

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接