【问题标题】:Pass WinMain (or wWinMain) arguments to normal main将 WinMain(或 wWinMain)参数传递给普通 main
【发布时间】:2014-12-08 17:51:42
【问题描述】:

如果您尝试将构建类型从 Console (/SUBSYSTEM:CONSOLE) 更改为 Windows (/SUBSYSTEM:WINDOWS),您将收到一条错误消息,提示缺少入口点 WinMain:

我认为解决此问题的最佳方法是从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 参数?

【问题讨论】:

  • argv 数组必须由NULL 指针终止,因此argv[argc] 始终是一个有效的表达式并且是一个NULL 指针,这意味着您必须创建一个数组一个条目,它是一个NULL 指针并作为第二个参数传递给main。
  • 这将解决崩溃,但仍然不会将真正的参数传递给我的函数。还是谢谢你。
  • @RSahu 我已经在打开的标签中。但它并没有真正回答这个问题 - 或者是吗?
  • 它立即对我有用,但里程可能会有所不同,并且没有特定的“正确”方式来做任何事情,只有适合您的方式。祝你好运。

标签: c++ winapi


【解决方案1】:

一种方法是使用CommandLineToArgvW() 将GetCommandLineW() 的结果解析为argv 样式的UTF-16 编码字符串数组,然后使用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()。整个事情看起来很复杂……
【解决方案2】:

您可以使用CommandLineToArgvW 解析命令行并将其转换为“普通”C 主样式函数所期望的格式。

 int argc;
 LPWSTR *argvw = CommandLineToArgvW(GetCommandLineW(), &argc);

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

请注意,这是宽字符,因为 Windows 本身需要 utf-16 命令行参数。如果 InitializeMagick 只使用窄字符,您也必须转换它们(可以使用 wcstombs_s 完成,其中隐含警告

【讨论】:

  • 标准主定义为int main(int, char**)。但是LPWSTR* 无法转换为char*(并且&amp;(LPWSTR*) 不会转入char**)。所以我可能需要以某种方式进行转换......
猜你喜欢
  • 2012-03-03
  • 1970-01-01
  • 2017-06-14
  • 2014-06-28
  • 2010-12-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-03-17
相关资源
最近更新 更多