文章目錄
- 程序
-
- 程序必須有一個線程
- 程序銷毀
-
- 主線程的入口點函數傳回(推薦)
- 調用ExitProcess 強制退出(不推薦)
- 在另一個程序調用TerminalProcess(不推薦)
- 連結器子系統開關
-
- /Subsystem:console 控制台程式 入口
- /Subsystem:Windows GUI程式 入口
- main函數運作生命周期
-
- C運作時庫函數
- main函數運作生命周期
- exit(0),ExitProcess,和TerminateProcess
- 獲得系統
- 總結
程序
程序必須有一個線程
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