1、应用程序的进入点
应用程序类型 进入点 嵌入可执行文件的启动函数
-------------------------------------------------------------------------------
需要ANSI字符和字符串的GUI应用程序 WinMain WinMainCRTStartup
需要Unicode字符和字符串的GUI应用程序 wWinMain wWinMainCRTStartup
需要ANSI字符和字符串的CUI应用程序 main mainCRTStartup
需要Unicode字符和字符串的CUI应用程序 wmain wmainCRTStartup
(VC++)如果不为链接器指定/SUBSYSTEM序开关的时候,链接程序能够自动确定应用程序应该连接到哪个
子系统:
当进行链接时,链接程序要查看代码中存在4个函数(WinMain、wWinMain、main或wmain)中的哪一个。
然后确定可执行程序应该是哪一个子系统,并且确定可执行程序中应该嵌入哪个C/C++启动函数。
这样提供了最大的灵活性。
2、程序能够使用的C/C++运行期全局变量(包含stdlib.h)
变量名 类型 说明
-------------------------------------------------------------------------------------------
--
_osver unsignedint 操作系统的测试版本。例如,Windows2000Beta3是测
试版本2031。因此_osver的值是2031
_winmajor unsignedint 采用十六进制表示法的Windows主要版本。对于Windows
2000来说,它的值是5
_winminor unsignedint 采用十六进制表示法的Windows次要版本。对于Windows
2000来说,它的值是0
_winver unsignedint (_winmajor<<8)+_winminor在命令行上传递的参数号
__argc unsignedint
__argv char** 带有指向ANSI/Unicode字符串的指针的__argc大小的数组
__wargv wchar_t** 每个数组项均指向一个命令行参数
_environ char** 指向ANSI/Unicode字符串的指针的数组。每个数组项指向
一个环境字符串
_wenviron wchar_t**
_pgmptr char* 正在运行的程序的ANSI/Unicode全路径和名字
_wpgmptrwchar_t*
3、DLL的内存基地址
调用GetModuleHandle并传递NULL值,就会返回进程的地址空间中可执行文件的基地址。因此,
即使通过包含在DLL中的代码来调用(NULL),返回的值也是可执行文件的基地址,而不是
DLL文件的基地址。
[注:]可以通过DllMain函数的第一个参数,要获得DLL文件的基地址。
3、关于CreateProcess
CreateProcess函数的lpCommandLine参数类型为LPTSTR。
这意味着CreateProcess期望你将传递一个非常量字符串的地址。从内部来讲,CreateProcess实际上要修
改你传递
给它的命令行字符串。不过,在CreateProcess返回之前,它将该字符串恢复为它的原始形式。
这个问题很重要,因为如果命令行字符串不包含在文件映象的只读部分中,就会出现违规访问的问题(尽
管某些情况下可能不会出现问题)。
比如下面的代码:
CreateProcess(NULL, TEXT("NOTEPAD"),...);
因为VC++在默认情况下是把常量字符串"NOTEPAD"放入只读内存的。
(参看VC的/Gf /GF编译开关)
应用程序类型 进入点 嵌入可执行文件的启动函数
-------------------------------------------------------------------------------
需要ANSI字符和字符串的GUI应用程序 WinMain WinMainCRTStartup
需要Unicode字符和字符串的GUI应用程序 wWinMain wWinMainCRTStartup
需要ANSI字符和字符串的CUI应用程序 main mainCRTStartup
需要Unicode字符和字符串的CUI应用程序 wmain wmainCRTStartup
(VC++)如果不为链接器指定/SUBSYSTEM序开关的时候,链接程序能够自动确定应用程序应该连接到哪个
子系统:
当进行链接时,链接程序要查看代码中存在4个函数(WinMain、wWinMain、main或wmain)中的哪一个。
然后确定可执行程序应该是哪一个子系统,并且确定可执行程序中应该嵌入哪个C/C++启动函数。
这样提供了最大的灵活性。
2、程序能够使用的C/C++运行期全局变量(包含stdlib.h)
变量名 类型 说明
-------------------------------------------------------------------------------------------
--
_osver unsignedint 操作系统的测试版本。例如,Windows2000Beta3是测
试版本2031。因此_osver的值是2031
_winmajor unsignedint 采用十六进制表示法的Windows主要版本。对于Windows
2000来说,它的值是5
_winminor unsignedint 采用十六进制表示法的Windows次要版本。对于Windows
2000来说,它的值是0
_winver unsignedint (_winmajor<<8)+_winminor在命令行上传递的参数号
__argc unsignedint
__argv char** 带有指向ANSI/Unicode字符串的指针的__argc大小的数组
__wargv wchar_t** 每个数组项均指向一个命令行参数
_environ char** 指向ANSI/Unicode字符串的指针的数组。每个数组项指向
一个环境字符串
_wenviron wchar_t**
_pgmptr char* 正在运行的程序的ANSI/Unicode全路径和名字
_wpgmptrwchar_t*
3、DLL的内存基地址
调用GetModuleHandle并传递NULL值,就会返回进程的地址空间中可执行文件的基地址。因此,
即使通过包含在DLL中的代码来调用(NULL),返回的值也是可执行文件的基地址,而不是
DLL文件的基地址。
[注:]可以通过DllMain函数的第一个参数,要获得DLL文件的基地址。
3、关于CreateProcess
CreateProcess函数的lpCommandLine参数类型为LPTSTR。
这意味着CreateProcess期望你将传递一个非常量字符串的地址。从内部来讲,CreateProcess实际上要修
改你传递
给它的命令行字符串。不过,在CreateProcess返回之前,它将该字符串恢复为它的原始形式。
这个问题很重要,因为如果命令行字符串不包含在文件映象的只读部分中,就会出现违规访问的问题(尽
管某些情况下可能不会出现问题)。
比如下面的代码:
CreateProcess(NULL, TEXT("NOTEPAD"),...);
因为VC++在默认情况下是把常量字符串"NOTEPAD"放入只读内存的。
(参看VC的/Gf /GF编译开关)