日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Runtime library, CRT

發(fā)布時(shí)間:2023/12/14 编程问答 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Runtime library, CRT 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

?

首先 ,看一句知乎的片段:https://www.zhihu.com/question/39858721/answer/83472146:

“Lampson也在圖靈獎(jiǎng)獲獎(jiǎng)演講時(shí)曾說過一句話:Any problem in computer science can be solved with another level of indirection. (有人也說是David Wheeler說的)。 如由于計(jì)算機(jī)體系結(jié)構(gòu)與資源是“赤裸丑陋”的,于是抽象出來一層操作系統(tǒng)進(jìn)行計(jì)算機(jī)資源的管理與操作。而為了與操作系統(tǒng)交互,于是抽象出來了Runtime Library方式是System Call。而瀏覽器、編譯器、Office等上層應(yīng)用則僅需Runtime Library層交互即可,方式是Operating System API。”?? ----------- 正確性待考證!

--------- 以前,我只是接觸到了application調(diào)用OS API.

application調(diào)用OS API, 例如,調(diào)用createThread函數(shù),從此圖來看,這個(gè)函數(shù)是以Runtime Library的形式提供服務(wù)的。


?

結(jié)合下面的文章整理一下這篇好文:https://blog.csdn.net/mvtechnology/article/details/72674042


https://blog.csdn.net/luoweifu/article/details/49055933?? ------ 作者的知識(shí)很豐富!!::

什么是Runtime Library?

微軟官方解釋: https://docs.microsoft.com/en-us/cpp/c-runtime-library/crt-library-features?view=vs-2019

Runtime Library就是運(yùn)行時(shí)庫,也簡(jiǎn)稱CRT(C Run Time Library)。是程序在運(yùn)行時(shí)所需要的庫文件,通常運(yùn)行時(shí)庫是以Lib或Dll形式提供的。

Windows下C Runtime Library是微軟對(duì)C標(biāo)準(zhǔn)庫函數(shù)的實(shí)現(xiàn),這樣每個(gè)程序可以直接使用C標(biāo)準(zhǔn)庫的函數(shù);后來出現(xiàn)了C++,于是又在C Runtime Library基礎(chǔ)上開發(fā)了C++ Runtime Library,實(shí)現(xiàn)了對(duì)C++標(biāo)準(zhǔn)庫的支持。因此現(xiàn)在Windows下的C/C++運(yùn)行時(shí)庫既包含子C標(biāo)準(zhǔn)庫,也包含了C++標(biāo)準(zhǔn)庫。

如果你安裝了VS2010,在安裝目錄下的VC\crt\src下(如C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\crt\src)有運(yùn)行時(shí)庫(CRT)的源代碼,這里既有C的文件(如output.c、stdio.h等),也有C++的文件(如iostream、string)。---- 每種編譯器都自帶這些庫嗎。

在C Runtime Library出現(xiàn)之前,許多程序都使用C編寫,而這些程序都要使用標(biāo)準(zhǔn)的C庫,按照以前的方式每一個(gè)程序最終都要拷貝一份標(biāo)準(zhǔn)庫的實(shí)現(xiàn)到程序中,這樣同一時(shí)刻內(nèi)存中可能有許多份標(biāo)準(zhǔn)庫的代碼(一個(gè)程序一份),所以微軟出于效率的考慮把標(biāo)準(zhǔn)C庫做為動(dòng)態(tài)鏈接來實(shí)現(xiàn),這樣多個(gè)程序使用C標(biāo)準(zhǔn)庫時(shí)內(nèi)存中就只有一份拷貝了。

確切地說運(yùn)行時(shí)庫指的就是對(duì)這些底層的基礎(chǔ)功能實(shí)現(xiàn)的動(dòng)態(tài)庫(Dll),運(yùn)行時(shí)庫和普通的Dll一樣,只有程序用到了它才會(huì)被加載,沒有程序使用的時(shí)候不會(huì)駐留內(nèi)存的。(底層功能的庫才叫運(yùn)行時(shí)庫么)。話雖如此,但有多少系統(tǒng)的東西說不定也是用C寫的,這些東西的存在就使C運(yùn)行時(shí)庫存在于內(nèi)存中了,所以運(yùn)行時(shí)庫幾乎總是需要的。雖然說運(yùn)行時(shí)庫應(yīng)該是動(dòng)態(tài)庫,但習(xí)慣上我們把與動(dòng)態(tài)運(yùn)行時(shí)庫相同代碼編譯出來的靜態(tài)庫也稱為運(yùn)行時(shí)庫,VC++下的運(yùn)行時(shí)庫有ML、MLd、MT、MTd、MD、MD六種。
?


運(yùn)行時(shí)庫的主要作用:

  • ? 提供C標(biāo)準(zhǔn)庫(如memcpy、printf、malloc等)、C++標(biāo)準(zhǔn)庫(STL)的支持。
  • ??? 應(yīng)用程序添加啟動(dòng)函數(shù),啟動(dòng)函數(shù)的主要功能為將要進(jìn)行的程序初始化,對(duì)全局變量進(jìn)行賦初值,加載用戶程序的入口函數(shù)。

?????????? 不采用寬字符集的控制臺(tái)程序的入口點(diǎn)為mainCRTStartup(void)。下面我們以該函數(shù)為例來分析運(yùn)行時(shí)庫究竟為我們添加了怎樣的入口程序。這個(gè)函數(shù)在crt0.c中被定義,下列的代碼經(jīng)過了筆者的整理和簡(jiǎn)化:
?

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();/* 獲得環(huán)境信息 */_aenvptr = (char *) __crtGetEnvironmentStringsA();_setargv(); /* 設(shè)置命令行參數(shù) */_setenvp(); /* 設(shè)置環(huán)境參數(shù) */_cinit(); /* C數(shù)據(jù)初始化:全局變量初始化,就在這里!*/__initenv = _environ;mainret = main( __argc, __argv, _environ ); /*調(diào)用main函數(shù)*/exit( mainret ); }

從以上代碼可知,運(yùn)行庫在調(diào)用用戶程序的main或WinMain函數(shù)之前,進(jìn)行了一些初始化工作。初始化完成后,接著才調(diào)用了我們編寫的main或WinMain函數(shù)。只有這樣,我們的C語言運(yùn)行時(shí)庫和應(yīng)用程序才能正常地工作起來。

除了crt0.c外,C運(yùn)行時(shí)庫中還包含wcrt0.c、 wincrt0.c、wwincrt0.c三個(gè)文件用來提供初始化函數(shù)。wcrt0.c是crt0.c的寬字符集版,wincrt0.c中包含 windows應(yīng)用程序的入口函數(shù),而wwincrt0.c則是wincrt0.c的寬字符集版。
?


歷史發(fā)展的角度講解運(yùn)行時(shí)庫

1 從操作系統(tǒng)的角度出發(fā)

操作系統(tǒng)一般是用C寫的(因?yàn)槟菚r(shí)還沒有C++,C已經(jīng)算是最高級(jí)的計(jì)算機(jī)語言了),不管是Linux/Unix還是Windows底層都是大量的C代碼。

在開發(fā)操作系統(tǒng)相應(yīng)的應(yīng)用程序時(shí),很多的程序都會(huì)用到相同基礎(chǔ)功能的函數(shù)庫。為了方便開發(fā)就把經(jīng)常用到的底層的基礎(chǔ)函數(shù)封閉成庫(不然你每寫一個(gè)程序都要把這基礎(chǔ)功能實(shí)現(xiàn)的源代碼拷貝一份到自己的工程,或自己再實(shí)現(xiàn)一次),于是就有了C運(yùn)行時(shí)庫(C Runtime Library),也就是靜態(tài)庫libc.lib(Release版)、libcd.lib(Debug版)。

因?yàn)樵缙诘牟僮飨到y(tǒng)和程序都相應(yīng)簡(jiǎn)單,用戶的需求也不高,那時(shí)的操作系統(tǒng)還沒有多任務(wù)、多線程的概念。所以libc.lib、libcd.lib當(dāng)然只能支持單線程的程序,而無法支持多線程的程序,因此這個(gè)運(yùn)行時(shí)庫叫Single-Threaded。

后來,隨著計(jì)算機(jī)的普及和發(fā)展,計(jì)算機(jī)要完成的任務(wù)越來越多,人們對(duì)時(shí)間和性能的要求也越來越高,為滿足這些需求,操作系統(tǒng)就有了多任務(wù)的概念,也有了多線程的技術(shù)。而之前的運(yùn)行時(shí)庫libc.lib、libcd.lib只能用于單線程,已經(jīng)無法滿足很多程序的需要,于是多線程的運(yùn)行時(shí)庫也就應(yīng)運(yùn)而生,這就是libcmt.lib、libcmtd.lib。? 這解決了多線程的問題,但隨著程序的越來越復(fù)雜,一個(gè)程序可能會(huì)用到多個(gè)其他程序的庫,多個(gè)程序可能會(huì)用到相同的庫,導(dǎo)致多線程同時(shí)運(yùn)行時(shí),在內(nèi)存中會(huì)保存多份的相同的靜態(tài)庫。假設(shè)A程序使用了C.lib,B程序也使用了C.lib,A、B程序同時(shí)運(yùn)行時(shí),在內(nèi)存中就會(huì)同時(shí)存在兩份C.lib。


????????????? 靜態(tài)庫在內(nèi)存中的呈現(xiàn)方式

為了解決這個(gè)問題,就產(chǎn)生了動(dòng)態(tài)庫的技術(shù)。于是就有了動(dòng)態(tài)的運(yùn)行時(shí)庫Multi-threaded DLL、Multi-threaded DLL Debug。多個(gè)程序使用同一個(gè)動(dòng)態(tài)庫,在內(nèi)存中只會(huì)有一份,效果圖如下:

?

2 從語言的角度

我們都知道,先有了C語言,后來才在C的基礎(chǔ)上發(fā)展出了C++語言,而C++又對(duì)C兼容,相當(dāng)是C的一個(gè)超集。
一開始的運(yùn)行時(shí)庫,只是C的運(yùn)行時(shí)庫(C Runtime Library),包含了對(duì)C標(biāo)準(zhǔn)函數(shù)的實(shí)現(xiàn)。后來隨著C++的產(chǎn)生,又把C++程序運(yùn)行時(shí)要用的底層基礎(chǔ)庫加了進(jìn)去,就有了C/C++的運(yùn)行時(shí)庫(C/C++ Runtime Library),這時(shí)的運(yùn)行時(shí)庫既包含了標(biāo)準(zhǔn)C函數(shù)的實(shí)現(xiàn),也包含了C++ STL的實(shí)現(xiàn)。
?


在VS中設(shè)置運(yùn)行時(shí)庫的類型:

可以在Properties->Configuration Properties->C/C++->Code Generation->Runtime Library中設(shè)置采用的運(yùn)行時(shí)庫的類型。

我們知道編譯出的靜態(tài)庫只有一個(gè)ProjectName.lib文件,而編譯出的動(dòng)態(tài)庫有兩個(gè)文件:ProjectName.lib+ProjectName.dll,一個(gè)是導(dǎo)入庫,一個(gè)動(dòng)態(tài)庫。

VC++中有六種Runtime Library的類型:

你可以在VS的安裝目錄下找到這些庫文件,如C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\lib\? 和? C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\lib\amd64\中分別找到對(duì)應(yīng)32位和64位的libcmt.lib、libcmtd.lib、msvcrt.lib、msvcrtd.lib庫。

對(duì)于dll, 通過上面的表格你會(huì)發(fā)現(xiàn),多線程的動(dòng)態(tài)運(yùn)行時(shí)庫是 msvcrt.lib + msvcrtxx.dll,之所以是msvcrtxx.dll是因?yàn)槊恳粋€(gè)版本的VS使用的庫名稱還不一樣。而且還不止包含一個(gè)庫,除了主要的MSVCRT庫外,還有MSVCPRT、MSVCIRT庫。它們之間的對(duì)應(yīng)關(guān)系如下:

在你的VS安裝目錄下(如C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\redist\x64\Microsoft.VC100.CRT),及系統(tǒng)目錄C:\Windows\System32、C:\Windows\SysWOW64下都能找到對(duì)應(yīng)的.dll庫。

很多的軟件在發(fā)布自己的產(chǎn)品時(shí)也都會(huì)帶上這些DLL(防止用戶的操作系統(tǒng)沒有安裝VS,或在系統(tǒng)目錄下找不到對(duì)應(yīng)的DLL(windows系統(tǒng)會(huì)沒有這些文件么?)),如我電腦上的百度影音安裝目錄下就有MSVCR71.DLL(C:\Program Files (x86)\baidu\BaiduPlayer\4.1.2.286\MSVCR71.DLL),WPS的安裝目錄下有msvcr100.dll(C:\Program Files (x86)\WPS Office\9.1.0.5132\wtoolex\msvcr100.dll)和msvcp100.dll(C:\Program Files (x86)\WPS Office\9.1.0.5132\wtoolex\msvcp100.dll)。
?

(1). 靜態(tài)鏈接的單線程庫
靜態(tài)鏈接的單線程庫只能用于單線程的應(yīng)用程序, C 運(yùn)行時(shí)庫的目標(biāo)代碼最終被編譯在應(yīng)用程序的二進(jìn)制文件中。通過 /ML 編譯選項(xiàng)可以設(shè)置 Visual C++ 使用靜態(tài)鏈接的單線程庫。
(2). 靜態(tài)鏈接的多線程庫
靜態(tài)鏈接的多線程庫的目標(biāo)代碼也最終被編譯在應(yīng)用程序的二進(jìn)制文件中,但是它可以在多線程程序中使用。通過 /MT 編譯選項(xiàng)可以設(shè)置 Visual C++ 使用靜態(tài)鏈接的多線程庫。
該選項(xiàng)生成的可執(zhí)行文件運(yùn)行時(shí)不需要運(yùn)行時(shí)庫dll的參加,會(huì)獲得輕微的性能提升,但最終生成的二進(jìn)制代碼因鏈入龐大的運(yùn)行時(shí)庫實(shí)現(xiàn)而變得非常臃腫。當(dāng)某項(xiàng)目以靜態(tài)鏈接庫的形式嵌入到多個(gè)項(xiàng)目,則可能造成運(yùn)行時(shí)庫的內(nèi)存管理有多份,最終將導(dǎo)致致命的“Invalid Address specified to RtlValidateHeap”問題。
(3). 動(dòng)態(tài)鏈接的運(yùn)行時(shí)庫
動(dòng)態(tài)鏈接的運(yùn)行時(shí)庫將所有的 C 庫函數(shù)保存在一個(gè)單獨(dú)的動(dòng)態(tài)鏈接庫 MSVCRTxx.DLL 中, MSVCRTxx.DLL 處理了多線程問題。使用 /MD 編譯選項(xiàng)可以設(shè)置 Visual C++ 使用動(dòng)態(tài)。
鏈接時(shí)將按照傳統(tǒng)VC鏈接dll的方式將運(yùn)行時(shí)庫MSVCRxx.DLL的導(dǎo)入庫MSVCRT.lib鏈接,在運(yùn)行時(shí)要求安裝了相應(yīng)版本的VC運(yùn)行時(shí)庫可再發(fā)行組件包(當(dāng)然把這些運(yùn)行時(shí)庫dll放在應(yīng)用程序目錄下也是可以的)。 因/MD和/MDd方式不會(huì)將運(yùn)行時(shí)庫鏈接到可執(zhí)行文件內(nèi)部,可有效減少可執(zhí)行文件尺寸。當(dāng)多項(xiàng)目以MD方式運(yùn)作時(shí),其內(nèi)部會(huì)采用同一個(gè)堆,內(nèi)存管理將被簡(jiǎn)化,跨模塊內(nèi)存管理問題也能得到緩解。

/MDd 、 /MLd 或 /MTd 選項(xiàng)使用 Debug runtime library( 調(diào)試版本的運(yùn)行時(shí)刻函數(shù)庫 ) ,與 /MD 、 /ML 或 /MT 分別對(duì)應(yīng)。 Debug 版本的 Runtime Library 包含了調(diào)試信息,并采用了一些保護(hù)機(jī)制以幫助發(fā)現(xiàn)錯(cuò)誤,加強(qiáng)了對(duì)錯(cuò)誤的檢測(cè),因此在運(yùn)行性能方面比不上 Release 版本。

/MD和/MDd將是潮流所趨,/ML和/MLd方式請(qǐng)及時(shí)放棄,/MT和/MTd在非必要時(shí)最好也不要采用了。
?


在Windows下進(jìn)行C++的開發(fā),VS下的一項(xiàng)設(shè)置MT、MTd、MD和MDd卻經(jīng)常讓人搞迷糊,特別是你工程使用了很多第三庫的時(shí)候,及容易出現(xiàn)各種鏈接問題。看一下下面這個(gè)錯(cuò)誤提示:
LIBCMT.lib(_file.obj) : error LNK2005: ___initstdio already defined in libc.lib(_file.obj)
LIBCMT.lib(_file.obj) : error LNK2005: ___endstdio already defined in libc.lib(_file.obj)
?

?


REF:

https://blog.csdn.net/mvtechnology/article/details/72674042

https://blog.csdn.net/u012372584/article/details/78949261

總結(jié)

以上是生活随笔為你收集整理的Runtime library, CRT的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。