intmain(intargc,char*argv[]){printf("HelloC!/n");return0;}//HelloCPP1.cpp#includeintmain(intargc,char*argv[]){std::cout<<"HelloCPP!/n";return0;}//HelloCPP2.cpp#includeusi" />

亚洲免费在线-亚洲免费在线播放-亚洲免费在线观看-亚洲免费在线观看视频-亚洲免费在线看-亚洲免费在线视频

Windows編程之從控制臺到SDK窗口

系統 1991 0

1 .典型 C/C++ 程序

2. Windows 編程的第一種方式是傳統的 SDK 方式, Windows 操作系統是由 C 語言編寫的,故可采用 C 語言直接調用 windows API 函數進行編程。

以下為 Win SDK 應用程序窗口程序框架示例及框架解析。

(1) 建立 Win32 應用程序項目 Win32SDK

Visual Studio 2005 à 文件 à 新建 à 項目 à Visual C++ à win32 à win32 項目 à win32 應用程序 à 空項目(默認使用 Unicode 字符集)。 如果運行時提示找不到 mfc80d.dll msvcr80d.dll 文件,在“項目屬性 à 配置屬性 à 清單工具 à 常規”中的“使用 FAT32 解決辦法”處選擇“是”,再重新生成解決方案。

(2) 添加源文件 Win32SDK.cpp

Windows編程之從控制臺到SDK窗口

3. Windows 下的 C/C++ 應用程序運行機制

1 subsystem 選項

VC6

Project Settings à C/C++ à Preprocessor à Preprocessor Definitions _CONSOLE _WINDOWS

Project Settings à C/C++ à Project Options /D "_CONSOLE" /D "_WINDOWS "

Project Settings à Link à Project Options /subsystem:console /subsystem:windows

VC2005

項目屬性 à C/C++ à 預處理器 à 預處理器定義: _CONSOLE _WINDOWS

項目屬性 à C/C++ à 命令行: /D "_CONSOLE" /D "_WINDOWS "

項目屬性 à 鏈接器 à 命令行: /SUBSYSTEM:CONSOLE /SUBSYSTEM:WINDOWS

項目屬性 à 鏈接器 à 系統 à 子系統:控制臺 (/SUBSYSTEM:CONSOLE) Windows (/SUBSYSTEM:WINDOWS)

2 )可執行文件的 Entry Point

可執行文件都有一個 Entry Point (起始地址), LINK 時可以用 /entry 指定。

缺省情況下,如果 subsystem “console” , Entry Point mainCRTStartup(ANSI) wmainCRTStartuup(UNICODE) ,即:

/subsystem:"console" /entry:"mainCRTStartup" (ANSI)

/subsystem:"console" /entry:"wmainCRTStartuup" (UNICODE)

mainCRTStartup wmainCRTStartuup 會調用用戶編寫的 main wmain 在進入可執行文件的代碼前,系統將會創建一個控制臺窗口。

值得一提的是,在進入應用程序的 Entry Point 前, Windows 的裝載器已經做過 C 變量的初始化,有初值的全局變量擁有了它們的初值,沒有初值的變量被設為 0 。

如果 subsystem “windows” , Entry Point WinMain(ANSI) wWinMain(UINCODE) ,即:

/subsystem:"windows" /entry:"WinMainCRTStartup" (ANSI)

/sbusystem:"windows" /entry:"wWinMainCRTStartup" (UINCODE)

WinMainCRTStartup wWinMainCRTStartup 會調用 用戶編寫的 WinMain wWinMain 。 窗口由用戶調用 CreateWindow(Ex) 創建 。

VC2005 中, 項目屬性 à 鏈接器 à 高級處有入口點選項,在編寫 Windows Mobile ANSI 控制臺程序時需指定入口點為 mainWCRTStartup WindowsCE (/SUBSYSTEM:WINDOWSCE) )。

VC2005 中,建一個簡單的 Console 程序( main 為入口函數),編譯后 F10 將進入 crtexe.c ,查看調用堆棧如下:

à int main ( int argc , char * argv [])

à int __tmainCRTStartup ( void )

à int mainCRTStartup ( void )

<1>mainCRTStartup 函數只是簡單的調用 __tmainCRTStartup 函數,其代碼如下:

#ifdef _WINMAIN_

int WinMainCRTStartup ( void ) // UNICODE 版本: int wWinMainCRTStartup(void)

#else

int mainCRTStartup ( void ) // UNICODE 版本: int wmainCRTStartup(void)

{

__security_init_cookie ();

return __tmainCRTStartup ();

}

<2>__tmainCRTStartup 函數調用 main/WinMain 函數,其代碼如下:

int __tmainCRTStartup ( void )

{

// ……

#ifdef _WINMAIN_

GetStartupInfo ( & StartupInfo );

……

mainret = WinMain (…) // UNICODE 版本: int wWinMain(…)

#else /* _WINMAIN_ */

mainret = main ( ); // UNICODE 版本: int wmain(…)

// ……

/*

* do C++ constructors (initializers) specific to this EXE

*/

if ( __native_startup_state == __initializing )

{

_initterm ( __xc_a , __xc_z );

__native_startup_state = __initialized ;

}

// ……

if ( ! managedapp )

exit ( mainret );

// ……

return mainret ;

}

可以推測上述 _WINMAIN_ 宏是與 subsystem 相關的一個 VC 編譯器內部宏。

(3)應用程序的啟動

程序是一連串 靜態 的指令,而進程是一個容器,它包含了一系列運行在這個程序實例上下文中的線程使用的資源。

當我們用鼠標點擊磁盤上的可執行文件 App.exe 后, App.exe 被裝載至內存后就形成了進程,因此進程是一個正在運行的程序的實例。一般我們可以同時啟動多個 App.exe 的實例,即創建同名的多個不同 ID 的進程。

進程內核對象不是進程本身,僅僅是一個系統用來管理這個進程的一個小的數據結構( PCB , Process Control Block )。進程是不活潑的,程序代碼的執行是線程的工作,線程是進程內執行代碼的獨立實體。一個進程要完成任何的事情,它必須有一個運行在其地址空間的線程。 Windows 操作系統調用 CreateProcess 函數創建一個新的進程和該進程的主線程,返回 LPPROCESS_INFORMATION 信息。 主線程通過執行 C/C++ 運行期啟動代碼初始化 C/C++ 運行期庫, C/C++ 運行期啟動代碼又會調用 main 函數。主線程在運行期間,可以調用 CreateThread 創建輔助線程,即所謂的多線程。

App.exe 進程的主線程入口函數 main/WinMain 返回后,啟動函數 mainCRTStartup __tmainCRTStartup )調用 C/C++ 運行期退出函數 exit( 參數為 main/WinMain 返回值 )

全局變量(包括內置類型和類類型)存儲在全局區。 exit 函數會銷毀所有全局的或靜態的 C++ 對象, 全局 C++ 對象的構造函數在進入應用程序的 Entry Point 之后,調用用戶編寫的 main/WinMain 之前調用。編譯器調用 atexit 記錄全局對象的析構函數( dynamic atexit destructor for 'x' , 多個函數形成多播鏈),在 exit 退出時( main/WinMain 返回之后)調用。

exit F11 進入 crt0dat.c 中的 doexit ,其中析構函數的調用代碼片段如下:

/*

* do _onexit/atexit() terminators(if there are any)

* These terminators MUST be executed in reverse order (LIFO)!

*/

_PVFV * onexitbegin = ( _PVFV *) _decode_pointer ( __onexitbegin );

_PVFV * onexitend = ( _PVFV *) _decode_pointer ( __onexitend );

// 依次調用 atexit 注冊的函數( oneixtbegin à onexitend

HelloCPP2.cpp 程序在 VC6 中,沒輸出 "X deconstructor" ,在 VC2005 中輸出 "X deconstructor"

最后( /* return to OS or to caller */ )調用 ExitProcess doexit à __crtExitProcess )促使操作系統終止應用程序。

參考:

在VC 中編譯、運行程序的小知識點

如何屏蔽控制臺應用程序的窗口?

《深入淺出 MFC 》第一章 à Win32 程序基本概念 à 進程與線程 à 一個進程的誕生與死亡

Windows 核心編程 第五版》 4.1 編寫第一個 Windows 應用程序。

Windows編程之從控制臺到SDK窗口


更多文章、技術交流、商務合作、聯系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!??!

發表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 青草青青在线视频观看 | 久草视频精品在线 | 国产一区二区三区亚洲欧美 | 久久亚洲国产视频 | 国产精品www视频免费看 | 国产欧美亚洲精品第二区首页 | 一级毛片无毒不卡直接观看 | 91精品国产91久久久久久 | 久久这里只有精品66re99 | 亚洲a视频在线 | 欧美网站www| 一区二区三区国产 | 久久久久久久一精品 | 欧美精品中文字幕手机免费视频 | 欧美在线播放一区二区 | 人成精品视频三区二区一区 | 精品免费久久久久久久 | 中文字幕日韩专区 | 激情爱爱视频 | 久久精品蜜芽亚洲国产a | 国产在线拍揄自揄视频不卡99 | 青青久在线视频免费视频 | 日韩欧美在线观看成人 | 日韩一区二区三区在线免费观看 | 亚洲啪啪免费视频 | av中文字幕在线 | 婷婷色婷婷 | 成年香蕉大黄美女美女 | 久久久久久久99精品免费观看 | 久久伦理 | 四房激情网 | 九九福利视频 | 国产1区2区三区不卡 | 久久天天躁狠狠躁夜夜躁综合 | 热久久视久久精品18国产 | 欧美一级久久 | 欧美 亚洲 一区 | 国产你懂得 | 国产在线视频你懂得 | 四虎国产永久在线观看 | 国产在线精品一区免费香蕉 |