MinGW,用控制台构建GUI应用程序

时间:2012-10-27 13:54:38

标签: windows debugging linker console mingw

我使用MinGW在Windows上构建我的应用程序。在编译和链接时,选项" -mwindows"在命令行中放置Win32 API函数。

更具体一点:在没有" -mwindows"的情况下调用MinGW的GCC时像这样:

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

' main.exe'在上面的2个命令行将使用控制台运行之后,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'

4 个答案:

答案 0 :(得分:15)

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

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

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

gcc -mconsole -mwindows main.c

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

答案 1 :(得分:6)

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

#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

答案 2 :(得分:1)

我找到了答案。取自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/

答案 3 :(得分:0)

您需要手动捕获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;

}