Mingw -mconsole选项导致MS GUI函数的未定义引用上的链接错误

时间:2017-06-26 13:05:29

标签: c mingw windows-console

有几次我被告知,mingw的-mwindows-mconsole命令行开关实际上只影响EXE头中的一个位,而不是太多其他位。然而,这似乎并非如此。如果我尝试在我的项目中使用-mconsole,我会在链接时收到以下错误:

../../build/objs/t-win32-ep128-xep128--gui.o:gui.c:(.text+0xb3): undefined reference to `_imp__GetOpenFileNameA@4'
../../build/objs/t-win32-ep128-xep128--gui.o:gui.c:(.text+0xc7): undefined reference to `_imp__CommDlgExtendedError@0'

好吧,我认为,与GUI相关的选项不能与-mconsole一起使用的问题。然而,这对我来说是一个陷阱,因为我需要编写一个使用像GetOpenFileName()这样的函数的应用程序但是它仍然需要控制台,因为我用printf()等编写调试消息。此外,-mconsole / -mwindows开关只会影响单个EXE标头元素,这似乎与“常识”观点相冲突,因此Windows将知道是否为应用程序分配控制台。是的,我可以自己分配一个控制台,但它很难看,因为我想使用程序启动的控制台。在这种情况下可以解决什么问题?感谢。

1 个答案:

答案 0 :(得分:2)

-mwindows-mconsole 确实只设置一个标志来确定Windows应用程序的类型。如果您未指定任何内容,则默认为console

也就是说,可能是默认链接选项在自动链接的库中有所不同。例如。对于GetOpenFileName(),您需要链接到comdlg32。以下示例按预期工作:

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

int main(void)
{
    OPENFILENAMEA ofn = {sizeof(ofn)};
    char filename[1024] = {0};
    ofn.lpstrFile = filename;
    ofn.nMaxFile = 1024;

    GetOpenFileNameA(&ofn);

    printf("selected: %s\n", filename);

    return 0;
}

输出:

$ gcc -oopendemo opendemo.c -lcomdlg32
$ ./opendemo.exe
selected: C:\temp\winsdksetup.exe

检查我的mingw gcc的行为,在没有任何库且没有-mwindows的情况下进行链接时,它会添加以下库:

  

-lmingw32 -lgcc -lgcc_eh -lmoldname -lmingwex -lmsvcrt -lpthread -ladvapi32 -lshell32 -luser32 -lkernel32 -lmingw32 -lgcc -lgcc_eh -lmoldname -lmingwex -lmsvcrt

-mwindows,列表如下:

  

-lmingw32 -lgcc -lgcc_eh -lmoldname -lmingwex -lmsvcrt -lpthread -lgdi32 -lcomdlg32 -ladvapi32 -lshell32 -luser32 -lkernel32 -lmingw32 -lgcc -lgcc_eh -lmoldname -lmingwex -lmsvcrt

确实,gdi32comdlg32会自动添加-mwindows,可能是因为许多 GUI程序需要它们。