在VC中編譯 執行程式的小知識點

2021-04-01 08:45:38 字數 4088 閱讀 9976

1、run-time library

run-time library是編譯器提供的標準庫,提供一些基本的庫函式和系統呼叫。

我們一般使用的run-time library是c run-time libraries。當然也有standard c++ libraries。

c run-time libraries實現ansi c的標準庫。vc安裝目錄的crt目錄有c run-time庫的大部分源**。

c run-time libraries有靜態庫版本,也有動態鏈結庫版本;有單執行緒版本,也有多執行緒版本;還有除錯和非除錯版本。

可以在"project"-"settings"-"c/c++"-"code generation"中選擇run-time library的版本。

動態鏈結庫版本:

/md multithreaded dll 使用導入庫msvcrt.lib

/mdd debug multithreaded dll 使用導入庫msvcrtd.lib

靜態庫版本:

/ml single-threaded 使用靜態庫libc.lib

/mld debug single-threaded 使用靜態庫libcd.lib

/mt multithreaded 使用靜態庫libcmt.lib

/mtd debug multithreaded 使用靜態庫libcmtd.lib

c run-time library的標準io部分與作業系統的關係很密切,在windows上,crt的io部分**只是乙個包裝,底層要用到作業系統核心kernel32.dll中的函式,在編譯時使用導入庫kernel32.lib。這也就是為什麼在嵌入式環境中,我們一般不能直接使用c標準庫。

在linux環境當然也有c標準庫,例如:

ld -o output /lib/crt0.o hello.o -lc

引數"-lc"就是在引用c標準庫libc.a。猜一猜"-lm"引用哪個庫檔案?

2、常見的編譯引數

vc建立專案時總會定義"win32"。控制台程式會定義"_console",否則會定義"_windows"。debug版定義"_debug",release版定義"ndebug"

與mfc dll有關的編譯常數包括:

_windll 表示要做乙個用到mfc的dll

_usrdll 表示做乙個使用者dll(相對mfc擴充套件dll而言)

_afxdll 表示使用mfc動態鏈結庫

_afxext 表示要做乙個mfc擴充套件dll

所以:regular, statically linked to mfc _windll,_usrdll

regular, using the shared mfc dll _windll,_usrdll,_afxdll

extension dll _windll,_afxdll,_afxext

cl.exe編譯所有原始檔,link.exe鏈結exe和dll,lib.exe產生靜態庫。

3、subsystem和可執行檔案的啟動

link的時候需要指定/subsystem,這個鏈結選項告訴windows如何執行可執行檔案。

控制台程式是/subsystem:"console"

其它程式一般都是/subsystem:"windows "

將 subsystem 選成"console"後,windows在進入可執行檔案的**前(如maincrtstartup),就會產生乙個控制台視窗。

如果選擇"windows",作業系統就不產生console視窗,該型別應用程式的視窗由使用者自己建立。

可執行檔案都有乙個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是winmaincrtstartup(ansi)或wwinmaincrtstartup(uincode),即:

/subsystem:"windows" /entry:"winmaincrtstartup" (ansi)

/sbusystem:"windows" /entry:"wwinmaincrtstartup" (uincode)

winmaincrtstartup 或 wwinmaincrtstartup 會呼叫 winmain 或 wwinmain。

這些入口點函式,在crt目錄都可以看到源**,例如(為了簡潔,我刪除了原**的一些條件編譯):

void maincrtstartup(void)

__except ( _xcptfilter(getexceptioncode(), getexceptioninformation()) )

/* end of try - except */

}"_t"是乙個巨集,對於ansi版本,"_twinmain"就是"winmain";對於uincode版本,"_twinmain"就是"wwinmain"。

4、不顯示console視窗的console程式

在預設情況下/subsystem 和/entry開關是匹配的,也就是:

"console"對應"maincrtstartup"或者"wmaincrtstartup"

"windows"對應"winmain"或者"wwinmain"

我們可以通過手動修改的方法使他們不匹配。例如:

#include "windows.h"

#pragma ***ment( linker, "/subsystem:/"windows/" /entry:/"maincrtstartup/"" ) // 設定入口位址

void main(void)

這個console程式就不會顯示console視窗。如果選/mld的話,這個程式只需要鏈結libcd.lib user32.lib kernel32.lib。

5、mfc的庫檔案

mfc的庫可以靜態鏈結,也可以動態鏈結。靜態庫和動態庫又有debug和release,ansi和unicode版本之分。

靜態mfc庫主要有:

ansi debug        nafxcwd.lib

ansi release      nafxcw.lib

unicode debug     uafxcwd.lib

unicode release   uafxcw.lib                       

動態鏈結庫主要有;

ansi debug         mfcxxd.lib (core,mfcxxd.dll),

mfcoxxd.lib (ole,mfcoxxd.dll),

mfcdxxd.lib (database,mfcdxxd.dll),

mf**xxd.lib (***work,mf**xxd.dll),

mfcsxxd.lib (static)

ansi release       mfcxx.lib (***bined,mfcxx.dll)

mfcsxx.lib (static)

unicode debug      mfcxxud.lib (core,mfcxxud.dll),

mfcoxxud.lib (ole,mfcoxxud.dll),

mfcdxxud.lib (database,mfcdxxud.dll),

mf**xxud.lib (***work,mf**xxud.dll),

mfcsxxud.lib (static)

unicode release    mfcxxu.dll (***bined,mfcxxu.dll),

mfcsxxu.lib (static)                       

C技巧 VC中編譯 執行程式的知識點 4

c技巧 vc中編譯 執行程式的知識點 4 5 mfc的庫檔案 mfc的庫可以靜態鏈結,也可以動態鏈結。靜態庫和動態庫又有debug和release,ansi和unicode版本之分。靜態mfc庫主要有 ansi debug nafxcwd.lib ansi release nafxcw.lib un...

OC中的小知識點

打個比方,你要造乙個家,物件導向的思想就是,找個工程師畫圖紙,找工人修房子,在阿里巴巴買建材,在蘇寧易購買家電,找搬家公司把家具搬進去,ok.類就是圖紙,打個比方,房子的圖紙就是類 類裡面有1.變數2.方法 宣告類的目的 告訴系統我們這個類中有哪些屬性和方法 類名 首字母大寫 nsobject 為了...

centos上編譯的可執行程式在suse上無法執行

在centos6.2上製作了乙個可執行程式,取名為aio test,其實是乙個利用libaio讀寫檔案的程式。在centos6.2上可以正常編譯,可以正常執行aio test。當我把aio test直接copy到乙個suse 10的機器上時,發現提示錯誤,找不到 lib64 libuuid.so a...