【问题标题】:MinGW, build GUI application with consoleMinGW,使用控制台构建 GUI 应用程序
【发布时间】:2012-10-17 12:53:31
【问题描述】:

我正在使用 MinGW 在 Windows 上构建我的应用程序。编译链接时在命令行中加入“-mwindows”选项,实现Win32 API函数。

更具体地说:在没有“-mwindows”的情况下调用 MinGW 的 GCC 时:

c:\>g++ -c main.cpp 
c:\>g++ -o main.exe main.o

上面2个命令行后面的'main.exe'会用控制台运行,Win32 API函数将无法使用。

当像这样使用“-mwindows”调用MinGW的GCC时:

c:\>g++ -c main.cpp
c:\>g++ -o main.exe main.o -mwindows

现在与“-mwindows”链接,“main.exe”可以使用 Win32 API,但是,当应用程序运行时它不会启动控制台。

这个“-mwindows”选项禁用控制台,这使我无法打印出调试信息。有什么方法可以同时保留控制台和“-mwindows”选项

【问题讨论】:

  • @rubenvb,不不,这与 Visual Studio 无关
  • 不一样。这里我们不讨论调试输出。部分答案可能重叠,但并不完全相同。还有一些特定于 VS 的答案。
  • 是的。我从命令行构建和运行,没有调试器

标签: windows debugging linker console mingw


【解决方案1】:

-mconsole 开关用于指定您希望以控制台子系统为目标。如果从控制台应用程序启动,您确实希望这样做以确保您的进程连接到现有控制台。例如,假设您确实按照您自己的答案定位了 GUI 子系统,然后调用 AllocConsole()。然后你会发现你的应用程序显示一个全新的控制台,而不是从另一个控制台应用程序启动时使用现有的控制台,例如cmd.exe.

如果您需要使用其他库,那么您可以使用-l 在命令行中随意添加它们。控制台应用程序没有什么特别之处,这意味着它不能链接到任何 Win32 API 函数。只是与-mconsole 关联的默认库集缺少一些您想要的库。

另一方面,您可以在构建应用时同时使用-mconsole-mwindows。它们并不相互排斥。

gcc -mconsole -mwindows main.c

这会生成一个以控制台子系统为目标的应用程序。您将获得自动链接的标准 -mwindows 组 Win32 库。这可能是实现目标的最简单方法。

【讨论】:

  • 我尝试在链接时添加-mconsole,但没有出现控制台
  • @PaulDinh Er,它对我有用。我采用了@Jarekczek 的程序,并完全按照我更新的答案对其进行了编译。输出一个控制台子系统。你真的不想使用AllocConsole 来做这件事。除非你想要 2 个控制台窗口!
  • 我永远不会想到加入这两个-m 开关。如果可以,那确实是最好的选择。
  • 谢谢。不知道你可以同时使用这两个选项
【解决方案2】:

我没有这个答案的证据,只有一些成功的实验。如果我有一个 hello 应用程序,像这样:

#include <stdio.h>
#include <windows.h>

int main(void)
{
    puts("hi");
    MessageBox(NULL, "test", "test", NULL);
    GetStockObject(0);
    return 0;
}

我不能-mconsole编译它,因为链接器抱怨GetStockObject。但是,当我在命令行上使用-lgdi32 开关 添加必要的库时,应用程序编译并干净地执行。也许这是同时保留控制台和 gdi 的方式。这是命令行:

gcc -mconsole test_gdi.c -lgdi32

【讨论】:

    【解决方案3】:

    我找到了答案。取自Using STDIN with an AllocConsole()

    AllocConsole();
    freopen("CONIN$", "r",stdin); 
    freopen("CONOUT$","w",stdout); 
    freopen("CONOUT$","w",stderr);  
    

    它就像魔术一样工作!

    “freopen”参考:http://www.cplusplus.com/reference/clibrary/cstdio/freopen/

    【讨论】:

    • 如果您的应用程序是从例如已经连接了控制台的命令提示符启动的,那将不会执行您想要的操作。
    • 你试过了吗?这种方法会产生两个控制台。
    • 错字。我的意思是回复为 -mconsole,选项 -mwindows 似乎使 -mconsole 不再像在我的 mingw 上那样有效
    • 您使用的是哪个版本的 mingw?无论如何,我已经说明了我的观点。您需要生成一个针对控制台子系统的 exe。我可以同时使用 -mconsole 和 -mwindows 来实现这一点。如果不能,请使用 -mconsole 并使用 -l 添加其他库。
    • 我有 4.6.3。我正在使用MS工具dumpbin /headers检查输出exe的子系统。
    【解决方案4】:

    您需要手动捕获 hInstance 和 nCmdShow(WinMain 参数)。您可以使用以下 C 函数来执行此操作:

    HINSTANCE GetHInstance( ) {
       return (HINSTANCE) GetModuleHandleW(NULL);
    }
        
    int GetNCmdShow() {
       STARTUPINFOW startupInfo;
       GetStartupInfoW(&startupInfo);
       if ((startupInfo.dwFlags & STARTF_USESHOWWINDOW) != 0) {
          return startupInfo.wShowWindow;
       }
       return SW_SHOWDEFAULT;
    }
    

    【讨论】:

      猜你喜欢
      • 2011-11-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-12-28
      • 1970-01-01
      • 2011-09-27
      相关资源
      最近更新 更多