2017年12月12日 星期二

C Runtime Library 的來歷, API, STL, MFC, ATL關系

 
C Runtime Library 的來歷, API, STL, MFC, ATL關系


msvcrt.dll (名稱:Microsoft C Runtime Library)提供了printf,malloc,strcpy等C語言庫函數,並且為使用C/C++(Vc)編繹的程序提供了初始化(如獲取命令行參數)以及退出等功能.


一、
Windows平台下的開發有多個不同的體系:標准C,Windows API,MFC,STL。這些都是預先編寫好的庫,實際開發時選哪個,取決於項目的規模和性質、程序的風格,還有個人的喜好。



1. CRT

  運行時庫就是C Run-Time Library,是C而非C++語言世界的概念。取這個名字就是因為你的C程序運行時需要這些庫中的函數。

  C語言是所謂的"小內核"語言,就其語言本身來說很小(不多的關鍵字,程序流程控制,數據類型等);所以,C語言內核開發出來之後, Dennis Ritchie 和 Brian Kernighan 就用C本身重寫了 90% 以上的 UNIX 系統函數,並且把其中最常用的部分獨立出來,形成頭文件和對應的 LIBRARY,C run-time library 就是這樣形成的。

  C Run-Time Library裡面含有初始化代碼,還有錯誤處理代碼(例如divide by zero處理)。你寫的程序可以沒有 math庫,程序照樣運行,只是不能處理復雜的數學運算,不過如果沒有了C Run-Time Library,main()就不會被調用,exit()也不能被響應。因為C Run-Time Library包含了C程序運行的最基本和最常用的函數。



2. Standard C++ Library

  到了 C++ 世界裡,有另外一個概念:Standard C++ Library,它包括了上面所說的C Run-Time Library和STL。包含C Run-Time Library的原因很明顯,C++ 是 C 的超集,沒有理由再重新來一個 C ++ run-time library。VC針對C++ 加入的Standard C++ Library主要包括:LIBCP.LIB, LIBCPMT.LIB和 MSVCPRT.LIB。



二、Microsoft的C\C++

1. Windows中的CRT

  CRT原先是指Microsoft開發的C Runtime Library,用於操作系統的開發及運行。後來在此基礎上開發了C++ Runtime Library,所以現在CRT是指Microsoft開發的C/C++ Runtime Library。在VC的CRT/SRC目錄下,可以看到CRT的源碼,不僅有C的,也有C++的。

  CRT原先的目的就是支持操作系統的運行。因為Windows操作系統除彙編部分外,都是用C/C++編寫的,所以內核及許多關鍵服務都在CRT上運行(它們都采用dll技術動態鏈接)。此外,用 VC編寫的C/C++程序也用到它們(可以動態鏈接,也可以靜態鏈接,前者運行時需要系統中已安裝CRT的dll,後者不需要)。可以說,CRT就是 Microsoft編寫Windows時使用的低層類庫。然後,它又被當作C++標准庫的一個實現包含在了VC系列中;我們在VC中使用的C++標准庫,其實就是CRT的一個真子集(少了C++標准所不包含的代碼,特別是大量的低層C代碼)

  C++標准,是C++的通用語言規範,指導所有C ++使用者。而CRT的其中一部分可以看作是Microsoft開發的一個C++標准庫實現(其實也確實如此,Microsoft在開發CRT時,參考了正在標准化過程中的C++語言規範)。它與C++標准有一定的差距,部分原因是,在C++沒有完成標准化之前,CRT已經開發並投入使用了。為了向下兼容以前的Windows代碼,早期的CRT與C++標准總有一定的差距。但是CRT確實在不斷的改進中。VC6帶的CRT與C++標准還有比較大的差距,而 VC8的幾乎完全符合C++標准了。


2. Windows中的CRT與Windows API

  至於CRT與WINDOWS API的關系,與許多人理解的相反,WINDOWS API作為Windows的一部份,是在CRT的基礎上開發的。你可以將Windows(及其API)看作一個項目,而這個項目使用的語言是彙編/C/C ++,使用的類庫就是CRT。所以,離開CRT,Windows API也無法使用的。

  在編寫操作系統時,你需要一個合適的低層庫,以便完成一些基本的、多次重復的工作。於是,就有了CRT。在最低層的時候,根本連DLL這個概念都沒有的,所以CRT的源代碼只能做成lib,被靜態鏈接。然後,隨著Windows越做越復雜,Microsoft提出了API的概念,它提供Windows開發者一組接口,可以直接操作Windows,這就是Windows API了。當然,Windows API也是在CRT之上編寫的。

  接著,Microsoft想給予C/C++程序員以足夠的支持,除了原始CRT之外,還要增加在Windows平台上編程所特有的東西,如thread等等。這些東西都是和平台相關的,只能建立在Windows API上。而這些新增內容,也被放進了CRT中。此時,CRT不僅僅包含最低層平台無關的代碼,還包括平台相關的部分。如你調用CRT的 _beginthread,其實內部調用了Windows API的CreateThread。加入這些東西後,CRT仍然被用作編寫操作系統;但是顯然,那些調用了Windows API的部分已經失去移值性了。

  然後,CRT被封裝成產品,隨編譯器一起發布。此時CRT產品的LIB和DLL都是Windows格式的,你不能在Windows以外的平台上使用EXE或DLL吧,這就是CRT和CRT產品的區別。Windows API的產品,或是Windows的其他許多組成部分也是一些LIB/DLL文件,這些都是表面的東西,是與Windows綁定在一起的。但是,如果你認為是先有Windows或Windows API,才有CRT的,那你就本末倒置了。除非你對CRT的定義就是那些LIB/DLL產品,而不包括用來產生它們的代碼。

  當然,CRT的一些組成部分也調用了Windows API。這可能就是有人認為CRT是建立的Windows API基礎上的原因。但是實際上,這一部分剝離CRT沒有任何的問題。只不過Microsoft將在Windows平台上可以使用的C/C++低層庫都加入到CRT中。因此,CRT中很大一部分是操作系統平台無關的(原始的CRT),是開發Windows本身及其上一切的基礎。它們也可以作為一個C/C+ +庫在其他操作系統平台上使用。還有一部分,則是和Windows緊密綁定的,調用Windows API來實現的,可以看作擴展的CRT。之所以將這兩部分放在一起,是因為它們都是開發Windows操作系統所需要的,也因為它們也都是Windows 平台上的C/C++程序員所需要的。這種復雜關系是Microsoft的人為因素造成的,不能因此認為CRT是建立在Windows或Windows API基礎上的。

  綜上,CRT(Microsoft's C/C++ Runtime Library)的一個真子集(主要是C++ Runtime Library)是一個符合(或至少是企圖符合)C++標准的C++庫。而Windows API(以及Windows的其他許多部分)都是在CRT的基礎上開發的。

  最後再說一句,C++當然不是Microsoft的專利。但是Microsoft選擇了C++,並取得了成功,這是肯定的了:像CRT,像VC,像Windows,像Office,像 SQL Server等等。



6)Windows環境下,VC提供的 C run-time library又分為動態運行時庫和靜態運行時庫。 
動態運行時庫主要是DLL庫文件msvcrt.dll(or MSVCRTD.DLL for debug build),對應的Import library文件是MSVCRT.LIB(MSVCRTD.LIB for debug build)


靜態運行時庫(release版)對應的主要文件是: 
LIBC.LIB (Single thread static library, retail version) 
LIBCMT.LIB (Multithread static library, retail version) 
msvcrt.dll提供幾千個C函數,即使是像printf這麼低級的函數都在msvcrt.dll裡。其實你的程序運行時,很大一部分時間時在這些運行庫裡運行。在你的程序(release版)被編譯時,VC會根據你的編譯選項(單線程、多線程或DLL)自動將相應的運行時庫文件  (libc.lib,libcmt.lib或Import library msvcrt.lib)鏈接進來。


編譯時到底哪個C run-time library聯入你的程序取決於編譯選項: 
/MD, /ML, /MT, /LD   (Use Run-Time Library)



http://blog.csdn.net/nodeathphoenix/article/details/8288233

沒有留言:

張貼留言