Windows支持两种类型的应用程序。
一是基于图形用户界面(GUI)的应用程序。(见:一个简单的windows GUI应用程序)
二是基于控制台用户界面(CUI)的应用程序。
用于CUI 应用程序的链接程序开关是/SUBSYSTEM:CONDOLE ,
用于G U I 应用程序的链接程序开关是/SUBSYSTEM : WINDOWS 。
当用户运行一个应用程序时,操作系统的加载程序就会查看可执行图形程序的标题,并抓取该子系统的值。
如果该值指明一个CUI应用程序,那么加载程序就会自动保证为该应用程序创建文本控制台窗口。
如果该值指明这是个G U I 应用程序,那么加载程序不创建控制台窗口,而只是加载应用程序。
Windows应用程序必须拥有一个在应用程序启动运行时调用的进入点函数。可以使用的进入点函数有4 个:
int WINAPI WinMain(HINSTANCE hinstExe, HINSTANCE, PSTR pszCmdLine, int nCmdShow);
int WINAPT wWinMain(HINSTANCE hinstExe,HINSTANCE, PWSTR pszCmdLine,int nCmdShow);
int __cdecl main(int argc,char *argv[],char *envp[]);
int _cdecl wmain(int argc, wchar_t *argv[], wchar_t *envp[]);
操作系统实际上并不调用你编写的进入点函数。它调用的是C/C++运行期启动函数。该函数负责对C/C++运行期库进行初始化,这样,就可以调用malloc 和free 之类的函数。它还能够确保已经声明的任何全局对象和静态C++对象能够在代码执行以前正确地创建。
下面说明源代 码中可以实现哪个进入点以及何时使用该进入点。
应用程序的进入点
应用程序类型 |
进入点 |
嵌入可执行文件的启动函数 |
需要ANSI字符和字符串的GUI应用程序 |
WinMain |
WinMainCRTStartup |
需要Unicode字符和字符串的GUI应用程序 |
wWinMainw |
WinMainCRTStartup |
需要ANSI字符和字符串的CUI应用程序 |
main |
mainCRTStartup |
需要Unicode字符和字符串的CUI应用程序 |
wmain |
wmainCRTStartup |
链接程序负责在它连接可执行文件时选择相应的C/C++运行期启动函数。
如果设定了/
SUBSYSTEM:WINDOWS链接程序开关,那么该链接程序期望找到一个WinMain或wWinmain函数。如果这两个函数都不存在,链接程序便返回一个“未转换的外部符号”的错误消息。否则,它可以分别选择WinMainCRTStartup函数或wWinMainCRTStartup 函数。
注意:链接程序负责在它连接可执行文件时选择相应的C/C++运行期启动函数。如果设定了/SUBSYSTEM:WINDOWS
链接程序开关,那么该链接程序期望找到一个WinMain 或wWinmain函数。如果这两个函数都不存在,链接程序便返回一个“未转换的外部符号”的错误消
息。否则,它可以分别选择WinMainCRTStartup函数或wWinMainCRTStartup函数。
启动函数的功能归纳如下:
• 检索指向新进程的完整命令行的指针。
• 检索指向新进程的环境变量的指针。
• 对C/C++运行期的全局变量进行初始化。如果包含了StdLib.h 文件,代码就能访问这些变量。
• 对C 运行期内存单元分配函数(malloc和calloc)和其他低层输入/输出例程使用的内存栈进行初始化。
• 为所有全局和静态C++类对象调用构造函数。
当进入点函数返回时:
启动函数便调用C 运行期的exit 函数,将返回值(nMainRetVal )传递给它。Exit 函数负责下面的操作:
• 调用由_onexit函数的调用而注册的任何函数。
• 为所有全局的和静态的C++类对象调用析构函数。
• 调用操作系统的ExitProcess函数,将nMainRetVal传递给它。这使得该操作系统能够撤消进程并设置它的exit代
变量名 |
类型 |
说明 |
_osver |
unsigned int |
操作系统的测试版本。例如Windows 2000 Beta 3是测试版本2031 。因此_osver的值是2031 |
_winmajor |
unsigned int |
采用十六进制表示法的Windows主要版本。对于Windows2000来说,它的值是5 |
_winminor |
unsigned int |
采用十六进制表示法的Windows次要版本。对于Windows2000来说,它的值是0 |
_winver |
unsigned int |
( _winmajor < < 8 ) + _ winminor在命令行上传递的参数号 |
__argc |
unsigned int |
带有指向ANSI/Unicode字符串的指针的__argc大小的数组 |
__argv |
char * * |
带有指向ANSI/Unicode字符串的指针的__argc大小的数组 |
__wargv |
wchar_t * * |
每个数组项均指向一个命令行参数 |
_environ |
char * * |
指向ANSI/Unicode字符串的指针的数组。每个数组项指向一个环境字符串 |
_wenviron |
wchar_t * * |
指向ANSI/Unicode字符串的指针的数组。每个数组项指向一个环境字符串 |
_pgmptr |
char * |
正在运行的程序的ANSI/Unicode全路径和名字 |
_wpgmptr |
wchar_t * |
正在运行的程序的ANSI/Unicode全路径和名字 |