Mingw -mconsole 选项导致 MS GUI 函数的未定义引用出现链接错误
Mingw -mconsole option causes linkage error on undefined referces for MS GUI functions
有人告诉我好几次,mingw 的 -mwindows
和 -mconsole
命令行开关实际上只影响 EXE header 左右的一个位,而没有太多其他.然而,这似乎不是真的。如果我尝试在我的项目中使用 -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'
OK,我想,GUI-related选项不能和-mconsole一起使用的问题。然而,这对我来说是一个陷阱,因为我需要编写一个使用 GetOpenFileName()
等函数的应用程序,但它仍然需要控制台,因为我在那里用 printf()
等编写调试消息。此外,它似乎与 "common knowledge" 的观点相冲突,即 -mconsole
/ -mwindows
开关仅影响单个 EXE header 元素,因此 Windows 将知道分配控制台或不为应用程序。是的,我可以自己分配一个控制台,但这很难看,因为我想使用程序启动的控制台。在这种情况下,解决方案是什么?谢谢。
-mwindows
和-mconsole
实际上只设置了一个标志来确定windows应用程序的类型。如果您不指定任何内容,则默认为 console
.
就是说,默认的 linking 选项可能与自动 linked 到的库不同。例如。对于 GetOpenFileName()
,您需要 link 到 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 的行为,当 linking 没有任何库且没有 -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
所以,确实,gdi32
和 comdlg32
会自动添加 -mwindows
,可能是因为 许多 GUI 程序需要它们。
有人告诉我好几次,mingw 的 -mwindows
和 -mconsole
命令行开关实际上只影响 EXE header 左右的一个位,而没有太多其他.然而,这似乎不是真的。如果我尝试在我的项目中使用 -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'
OK,我想,GUI-related选项不能和-mconsole一起使用的问题。然而,这对我来说是一个陷阱,因为我需要编写一个使用 GetOpenFileName()
等函数的应用程序,但它仍然需要控制台,因为我在那里用 printf()
等编写调试消息。此外,它似乎与 "common knowledge" 的观点相冲突,即 -mconsole
/ -mwindows
开关仅影响单个 EXE header 元素,因此 Windows 将知道分配控制台或不为应用程序。是的,我可以自己分配一个控制台,但这很难看,因为我想使用程序启动的控制台。在这种情况下,解决方案是什么?谢谢。
-mwindows
和-mconsole
实际上只设置了一个标志来确定windows应用程序的类型。如果您不指定任何内容,则默认为 console
.
就是说,默认的 linking 选项可能与自动 linked 到的库不同。例如。对于 GetOpenFileName()
,您需要 link 到 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 的行为,当 linking 没有任何库且没有 -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
所以,确实,gdi32
和 comdlg32
会自动添加 -mwindows
,可能是因为 许多 GUI 程序需要它们。