文章目录
进程必须有一个线程
PrimaryThread 主线程
进程销毁
主线程的入口点函数返回(推荐)
进程的所有线程自然死亡(几乎不出现)
要么进程所有线程都调用ExitThread
调用ExitProcess 强制退出(不推荐)
在进程的一个子线程中调用ExitProcess,
缺陷:
ExitProcess 后的代码会无法执行,会有资源没有释放,因为c/c++运行库也许不能执行正确的清理工作,包括全局对象的析构和本地对象的析构。
在另一个进程调用TerminalProcess(不推荐)
在另一个进程的任意线程中调用TerminalProcess,传入被终止的进程handle。
缺陷:
被终止进程得不到终止的通知,进程得不到正确清理,也不能阻止它被强行终止,但是操作系统会在终止后彻底清理的,确保不会泄露任何操作系统资源(进程的 内存,文件,内核对象计数,用户对象,GDI对象都会被销毁)。
链接器子系统开关
将子系统的正确类型嵌入最终生成的可执行文件。
visitual studio中设置子系统方式:属性-》链接器-》子系统
/Subsystem:console 控制台程序 入口
_tmain(Main):处理ascii字符和字符串的CUI程序(控制台程序)
对应嵌入可执行文件的启动函数 mainCRTStartup
_tmain(wMain):处理Unicode字符和字符串的CUI程序(控制台程序)
对应嵌入可执行文件的启动函数 wMainCRTStartup
/Subsystem:Windows GUI程序 入口
_tWinMain(WinMain):处理ascii字符和字符串的GUI程序(图形化程序)
对应嵌入可执行文件的启动函数 WinMainCRTStartup
_tWinMain(wWinMain):处理Unicode字符和字符串的GUI程序(图形化程序)
对应嵌入可执行文件的启动函数 wWinMainCRTStartup
main函数运行生命周期
C运行时库函数
这些C运行时库函数,主要完成以下任务:
- 获取进程命令行指针;
- 获取进程环境变量指针;
- 初始化C/C++运行时库的全局变量,如果你包含了头Stdlib.h,那么你就可以访问这些变量!//errno这就是一个全局变量。_enrion这是环境变量指针
- 初始化malloc函数的内存堆;
- 为C++全局类,调用构造函数。
malloc 函数,不要轻易使用,因为这个函数一般来说,最终会调用windows API函数,我们直接调用virtualAlloc windowsAPI函数,效率会高!
main函数运行生命周期
Kenerl 调用XXXCRTStartup函数;
XXXCRTStartup函数调用main函数;
main函数退出;
exit函数被调用(真正调用的是crt0dat.c中的)
static void __cdecl doexit (
int code,
int quick,
int retcaller
)
这个函数主要做以下事情:
1.调用_onexit函数注册的所有函数;
2.调用C++销毁函数销毁所有的全局和静态类对象;
3.如果_CRTDBG_LEAK_CHECK_DF标志被设置,那么调用CrtDumpMemoryLeaks函数,列出泄露内存。
4.调用ExitProcess函数,系统杀死当前进程!
exit(0),ExitProcess,和TerminateProcess
获得系统GetVersion() 获得版本号
#include <windows.h>
#include <stdio.h>
#include <VersionHelpers.h>
void main()
{
DWORD dwVersion = 0;
DWORD dwMajorVersion = 0;
DWORD dwMinorVersion = 0;
DWORD dwBuild = 0;
LPOSVERSIONINFOW lpVersionInformation;
dwVersion = GetVersion();//GetVersionEx(lpVersionInformation);
if (IsWindowsXPOrGreater()) {
printf("Yes\n");
};
printf("%0x\n",dwVersion);
// Get the Windows version.
//一个子就是WORD;
WORD Version=LOWORD(dwVersion);
//dwVersion中,其地位字,
dwMajorVersion = (DWORD)(LOBYTE(Version));
//Version字的低字节代表大版本号
dwMinorVersion = (DWORD)(HIBYTE(Version));
//Version字的高字节代表小版本号
// Get the build number.
if (dwVersion < 0x80000000)
dwBuild = (DWORD)(HIWORD(dwVersion));
//dwVersion的高位字,表示build号。
printf("Version is %d.%d (%d)\n",
dwMajorVersion,
dwMinorVersion,
dwBuild);
getchar();
}
总结
1.使用
C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\Common7\Tools
有一些工具 包括GuidGen.exe