在VC++中使用OpenCV,一般是建立一个 win32 console application 项目,当运行此类程序的时候,默认情况下会有一个类似DOS窗口的console窗口,供程序与用户之间交互之用。
但是有时候我们只想在程序中运行一段功能代码,不希望显示这个 console 窗口,而是让代码执行完毕之后程序自动退出。隐藏这种 win32 console application 的 console 窗口,主要有两种方式:
1、通过#pragma指令来修改,即在main函数前添加以下一行代码:
#pragma comment( linker, "/subsystem:/"windows/" /entry:/"mainCRTStartup/"" )
2、通过设置项目属性来修改,即在 Project –> Properties -> Configuration Properties –> Linker -> System 的 Subsystem 项中,将 Console (/SUBSYSTEM:CONSOLE) 修改为 Console (/SUBSYSTEM:WINDOWS) ,这样就把控制台程序窗口隐去了。
上述方法是通过设置编译器的链接开关来实现的,所以让我们来看一下编译器的链接开关选项(也就是 linker 选项)。
一、linker 的 /subsystem 选项:
该选项的语法形式如下:
/SUBSYSTEM:{CONSOLE | EFI_APPLICATION | EFI_BOOT_SERVICE_DRIVER |
EFI_ROM | EFI_RUNTIME_DRIVER | NATIVE | POSIX | WINDOWS | WINDOWSCE}
[,major[.minor]]
这个链接选项告诉操作系统如何运行可执行文件。
—— CONSOLE:
win32 字符模式应用程序,此种类型的应用程序在运行的时候会产生一个类似DOS窗口的控制台窗口。如果在应用程序的主函数为 main() 或者 wmain(),在默认情况下该应用程序就是一个控制台应用程序。
—— Extensible Firmware Interface (EFI_***):
这4种 EFI_*** 是和CPU具体架构相关的参数选项,并不常用,有兴趣的可以访问 intel 主页来查看相关内容。
—— NATIVE:
设备驱动器选项,如果 /DRIVER:WDM 选项被设定的话,该链接选项(NATIVE)就为默认选项。
—— POSIX:
在windows NT 种运行在POSIX子系统上的应用程序。
—— WINDOWS:
该类型的应用程序不产生console窗口,程序窗口由用户自己创建,简而言之就是一个标准的 Win32 application,其入口地址为 WinMain()函数或者 wWinMain()函数的地址。如果你在应用程序中定义的主函数为 WinMain 或者 wWinMain,在默认情况下该应用程序就是一个Win32 Application !
—— WINDOWSCE:
运行在 windows CE 上的应用程序。
—— major and minor (optional):
主版本号和次版本号,该选项为可选,该选项为0~65535之间的十进制整数。
从上面可以看出,如果我们建立一个 win32 console application 的话,linker 的 /subsystem 选项应该为CONSOLE,可以在 VC6 开发环境的 project->setting->link->project option 或者 VS2005/2008 开发环境的 Project –> Properties -> Configuration Properties –> Linker -> System 中看到!
二、应用程序是如何运行的!
我们知道用 VC 编写的程序,运行的时候是需要 C/C++ 运行库支持的。当我们运行一个 C/C++ 程序的时候,链接器会首先寻找应用程序的启动函数,例如:
如果你建立了一个 console 程序的话,编译器的链接开关会是以下这种形式:
/subsystem:"console" /entry:"mainCRTStartup" (ANSI)
/subsystem:"console" /entry:"wmainCRTStartuup" (UNICODE)
如果你建立了一个win32 application,编译器的链接开关则会是以下形式:
/subsystem:"windows" /entry:"WinMain" (ANSI)
/sbusystem:"windows" /entry:"wWinMain" (UINCODE)
上面的两种形式可以在 Project –> Properties -> Configuration Properties –> Linker -> System (VS2005/08)中看到,其中的 subsystem 和 entry 并不需要都设置,如果你只设置了 /subsystem:"console" 的话,那么默认的 entry 开关应为 /entry:"mainCRTStartup";反之,如果你在应用程序中定义了 main 函数的话,默认情况下,你的 /subsystem 开关应该为 /system:"console"。
在默认情况下,/subsystem 和 /entry 开关是匹配的,也就是 console 对应 mainCRTStartup 或者 wmainCRTStartup;windows 对应 WinMain 或者 wWinMain。
但是我们也可以通过手动改动的方式使他们不匹配,例如我们可以这样改动:
#pragma comment( linker, "/subsystem:/"windows/" /entry:/"mainCRTStartup/"" ) // 设置入口地址
int main(int argc, char* argv[])
{
MessageBox(NULL, "hello", "Notice", MB_OK);
return 0;
}
在默认情况下,链接器看到 /subsystem 下是 windows 选项的时候,它会自动寻找 WinMain 或者 wWinMain,
但我们强制指定入口地址,这样运行程序的时候默认的console窗口就会隐藏!
上面是在代码中使用 #pragma 指令来设置,还有一种就是直接在开发环境的Project –> Properties -> Configuration Properties –> Linker -> System (VS2005/08)中手工改动!