Visual C++中的C運行時庫淺析
隨著操作系統多線程技術的發展,最初的C運行時庫無法滿足程序的 需求 ,出現了嚴重的問題。C運行時庫使用了多個全局變量(例如errno)和靜態變量,這可能在多線程程序中引起沖突。假設兩個線程都同時設置errno,其結果是后設置的errno會將先前的覆蓋,用戶得
隨著操作系統多線程技術的發展,最初的C運行時庫無法滿足程序的
需求,出現了嚴重的問題。C運行時庫使用了多個全局變量(例如errno)和靜態變量,這可能在多線程程序中引起沖突。假設兩個線程都同時設置errno,其結果是后設置的errno會將先前的覆蓋,用戶得不到正確的錯誤信息。
因此,Visual
C++提供了兩種版本的C運行時庫。一個版本供單線程應用程序調用,另一個版本供多線程應用程序調用。多線程運行時庫與單線程運行時庫有兩個重大差別:
?。?)類似errno的全局變量,每個線程單獨設置一個;
這樣從每個線程中可以獲取正確的錯誤信息。
?。?)多線程庫中的數據結構以同步機制加以保護。
這樣可以避免訪問時候的沖突。
Visual C++提供的多線程運行時庫又分為靜態鏈接庫和動態鏈接庫兩類,而每一類運行時庫又可再分為de
bug版和release版,因此Visual C++共提供了6個運行時庫。如下表:
C運行時庫 |
庫文件 |
Single thread(static link) |
libc.lib |
Debug single thread(static link) |
libcd.lib |
MultiThread(static link) |
libcmt.lib |
Debug multiThread(static link) |
libcmtd.lib |
MultiThread(dynamic link) |
msvert.lib |
Debug multiThread(dynamic link) |
msvertd.lib |
2.C運行時庫的作用 C運行時庫除了給我們提供必要的庫函數調用(如memcpy、printf、malloc等)之外,它提供的另一個最重要的功能是為應用程序添加啟動函數。
C運行時庫啟動函數的主要功能為進行程序的初始化,對全局變量進行賦初值,加載用戶程序的入口函數。
不采用寬字符集的控制臺程序的入口點為mainCRTStartup(void)。下面我們以該函數為例來分析運行時庫究竟為我們添加了怎樣的入口程序。這個函數在crt0.c中被定義,下列的代碼經過了筆者的整理和簡化:
clearcase/" target="_blank" >cccccc width="90%" align=center bgColor=#e3e3e3 border=1>
void mainCRTStartup(void) { int mainret; /*獲得WIN32完整的版本信息*/ _osver = GetVersion(); _winminor = (_osver >> 8) & 0x00FF ; _winmajor = _osver & 0x00FF ; _winver = (_winmajor << 8) + _winminor; _osver = (_osver >> 16) & 0x00FFFF ;
_ioinit(); /* initialize lowio */
/* 獲得命令行信息 */ _acmdln = (char *) GetCommandLineA();
/* 獲得環境信息 */ _aenvptr = (char *) __crtGetEnvironmentStringsA();
_setargv(); /* 設置命令行參數 */ _setenvp(); /* 設置環境參數 */
_cinit(); /* C數據初始化:全局變量初始化,就在這里!*/
__initenv = _environ; mainret = main( __argc, __argv, _environ ); /*調用main函數*/
exit( mainret ); } |
從以上代碼可知,運行庫在調用用戶程序的main或WinMain函數之前,進行了一些初始化工作。初始化完成后,接著才調用了我們編寫的main或WinMain函數。只有這樣,我們的C語言運行時庫和應用程序才能正常地工作起來。
除了crt0.c外,C運行時庫中還包含wcrt0.c、 wincrt0.c、wwincrt0.c三個文件用來提供初始化函數。wcrt0.c是crt0.c的寬字符集版,wincrt0.c中包含
windows應用程序的入口函數,而wwincrt0.c則是wincrt0.c的寬字符集版。
Visual C++的運行時庫源代碼缺省情況下不被安裝。如果您想查看其源代碼,則需要重裝Visual C++,并在重裝在時選中安裝運行庫源代碼選項。