目錄
1、概述
2、不同版本的Visual Studio對應的運行時庫說明
3、在Windbg10.0安裝目錄中獲取UCRT通用運行時庫
4、微軟官網對UCRT通用運行時庫的相關說明
5、使用Visual Studio 2017開發軟件初期遇到的UCRT通用運行時庫問題
6、如何查看軟件依賴了哪些C/C++運行時庫?
7、將軟件從32位升級到64位后,要使用64位UCRT通用運行時庫
8、發布軟件時未打包C/C++運行時庫的項目問題實例
C++軟件異常排查從入門到精通系列教程(專欄文章列表,歡迎訂閱,持續更新...)https://blog.csdn.net/chenlycly/article/details/125529931C/C++基礎與進階(專欄文章,持續更新中...)
https://blog.csdn.net/chenlycly/category_11931267.htmlVC++常用功能開發匯總(專欄文章列表,歡迎訂閱,持續更新...)
https://blog.csdn.net/chenlycly/article/details/124272585C++軟件分析工具從入門到精通案例集錦(專欄文章,持續更新中...)
https://blog.csdn.net/chenlycly/article/details/131405795開源組件及數據庫技術(專欄文章,持續更新中...)
https://blog.csdn.net/chenlycly/category_12458859.html網絡編程與網絡問題分享(專欄文章,持續更新中...)
https://blog.csdn.net/chenlycly/category_2276111.html? ? ? ?大家在開發C++軟件的過程中,會時不時遇到這樣或那樣的C/C++運行時庫相關問題。今天結合多年的C++軟件開發經驗,給大家詳細介紹一下C/C++運行時庫以及以api-ms-win-開頭的UCRT系統通用運行時庫,并給出了項目問題分析實例,以供大家借鑒或參考。
1、概述
? ? ? ?使用Visual Studio開發的C++應用程序,在發布時需要將C/C++運行時庫一起打包到安裝包中,安裝時將C/C++運行時庫放置到exe主程序的安裝目錄中。C++應用程序調用的C/C++運行時函數(比如abort、system、strlen、strcpy等)以及C++標準庫,都在C/C++運行時庫中。C++應用程序依賴這些C/C++運行時庫,啟動時需要加載這些運行時庫。
? ? ? ?為啥要帶上C/C++運行時庫呢?如果機器上安裝了Visual Studio,在安裝Visual Studio時會自動將對應版本的運行時庫拷貝到系統目錄C:\Windows\System32(在64位系統中,32位版本的運行時庫會拷貝到C:\Windows\SysWOW64目錄中)。如果機器上沒有安裝Visual Studio,系統目錄中一般不會有這些C/C++運行時庫,如果此時安裝目錄中也沒有,則程序啟動時會因為在系統中找不到這些庫而啟動失敗。
2、不同版本的Visual Studio對應的運行時庫說明
? ? ? ? 我們代碼中調用的很多C/C++基本庫函數都位于C/C++運行時庫中,比如abort、system、strlen、strcpy等運行時庫函數。一般運行時庫是以msvcr(C運行時庫)或msvcp(C++運行時庫)開頭的。
? ? ? ?不同版本的Visual Studio攜帶的C/C++運行時庫的名稱也不一樣,這些運行時庫一般要打包到安裝程序中,安裝時要拷貝到exe主程序的安裝目錄中。
? ? ? ?對于不同版本的Visual Studio對應的運行時庫版本,很多人可能分不清楚,會有疑惑,這里詳細給大家介紹一下:(以d結尾的是Debug版本的運行時庫)
1)VS2010對應的運行時庫文件(對應100版本):msvcp100.dll(msvcp100d.dll)、msvcr100.dll(msvcr100d.dll);
2)VS2012對應的運行時庫文件(對應110版本):msvcp110.dll(msvcp110d.dll)、msvcr110.dll(msvcr110d.dll);
3)VS2013對應的運行時庫文件(對應120版本):msvcp120.dll(msvcp120d.dll)、msvcr120.dll(msvcr120d.dll);
4)VS2017對應的運行時庫文件(對應140版本):msvcp140.dll(msvcp140d.dll)、vcruntime140.dll(vcruntime140d.dll)、u以及UCRT通用運行時庫(ucrtbase.dll(ucrtbased.dll)+ 多個以api-ms-win-開頭的dll庫)。 (VS2017引入了兩類新庫vcruntime140.dll和UCRT,不再有msvcr140.dll庫,只保留了msvcp140.dll庫)
? ? ? ?在Visual Studio 2015之前的版本中,C/C++運行時庫主要由msvcrXXX.dll和msvcpXXX.dll,其中XXX是對應Visual Studio版本對的數字,如上所示。 在Visual Studio 2015中,C/C++運行時庫被分離重構,分離成msvcp、vcruntime和UCRT,在Visual Studio 2015及以后的版本中,均使用這種新的結構。
? ? ? ?UCRT,全稱為The Universal CRT,Windows系統通用運行時庫,主要由ucrtbase.dll以及api-ms-win-開頭的多個dll庫,如下所示:
3、在Windbg10.0安裝目錄中獲取UCRT通用運行時庫
? ? ? ?使用Visual Studio 2015及以上版本開發的C++應用程序,發布時都要帶上這些通用運行時庫。這些UCRT通用運行時庫可以從Windows SDK中獲取。比如可以從安裝的Windbg10.0的安裝目錄中找到這些UCRT通用庫,當時Windbg10.0就是使用Windows SDK安裝的,所以安裝目錄中可以找到UCRT運行時庫。比如我本機的安裝目錄:
C:\Program Files (x86)\Windows Kits\10\Redist\10.0.17763.0\ucrt\DLLs
在上述路徑中可以找到,如下所示:(可以在Windbg安裝目錄中以api-ms-win為關鍵字搜索,找到具體的路徑)
可以將這些路徑下的通用運行時庫拷貝到項目中,發布版本時要將這些運行時庫帶上。
? ? ? ?在這里,給大家重點推薦一下我的幾個熱門暢銷專欄,歡迎訂閱:(博客主頁還有其他專欄,可以去查看)
專欄1:(該精品技術專欄的訂閱量已達到430多個,專欄中包含大量項目實戰分析案例,有很強的實戰參考價值,廣受好評!專欄文章持續更新中,預計更新到200篇以上!歡迎訂閱!)
C++軟件異常排查從入門到精通系列教程(專欄文章列表,歡迎訂閱,持續更新...)https://blog.csdn.net/chenlycly/article/details/125529931
本專欄根據多年C++軟件異常排查的項目實踐,系統地總結了引發C++軟件異常的常見原因以及排查C++軟件異常的常用思路與方法,詳細講述了C++軟件的調試方法與手段,以圖文并茂的方式給出具體的項目問題實戰分析實例(很有實戰參考價值),帶領大家逐步掌握C++軟件調試與異常排查的相關技術,適合基礎進階和想做技術提升的相關C++開發人員!
考察一個開發人員的水平,一是看其編碼及設計能力,二是要看其軟件調試能力!所以軟件調試能力(排查軟件異常的能力)很重要,必須重視起來!能解決一般人解決不了的問題,既能提升個人能力及價值,也能體現對團隊及公司的貢獻!
專欄中的文章都是通過項目實戰總結出來的,包含大量項目問題實戰分析案例,有很強的實戰參考價值!專欄文章還在持續更新中,預計文章篇數能更新到200篇以上!
專欄2:?
C/C++基礎與進階(專欄文章,持續更新中...)https://blog.csdn.net/chenlycly/category_11931267.html
以多年的開發實戰經驗為基礎,總結并講解一些的C/C++基礎與進階內容,以圖文并茂的方式對C++相關知識點進行詳細地展開與剖析!專欄涉及了C/C++開發領域多個方面的內容,同時給出C/C++及網絡方面的常見筆試面試題,并詳細講述Visual Studio常用調試手段與技巧!
專欄3:?
VC++常用功能開發匯總https://blog.csdn.net/chenlycly/article/details/124272585
專欄將10多年C++開發實踐中常用的功能,以高質量的代碼展現出來,并對相關功能的實現細節進行了詳細的說明。這些常用的代碼,其質量與穩定性是有保證的,可以直接拿過去使用,可以有效地解決C++軟件開發過程中遇到的問題。
4、微軟官網對UCRT通用運行時庫的相關說明
? ? ? ?微軟官網也有介紹UCRT通用運行時庫的相關介紹,直接在Microsoft Learn: Build skills that open doors in your career上搜索UCRT,會搜索到如下結果:
?
點擊“將代碼升級到通用 CRT”這一項,進入頁面,其鏈接為:(此處提供英文版本的鏈接,如果要查看中文,可以在頁面底部左下角的語言切換欄切換成中文)
Upgrade your code to the Universal CRThttps://learn.microsoft.com/en-us/cpp/porting/upgrade-your-code-to-the-universal-crt?view=msvc-170在該網頁中可以看到如何獲取UCRT運行時庫,如下所示:
?5、使用Visual Studio 2017開發軟件初期遇到的UCRT通用運行時庫問題
? ? ? ? 我們項目之前使用Visual Studio 2010開發的,后來因為使用了Visual Studio 2017編譯的開源WebRTC庫,將Visual Studio升級到了2017版本。最開始并不知道UCRT通用運行時庫的存在,在發布版本時沒有將這些以api-ms-win-開頭的通用運行時庫帶上,導致在部分機器上啟動程序時會報錯:
?后來查看騰訊會議、WPS和企業微信等程序的安裝目錄中均有帶上多個以api-ms-win-開頭多個dll庫:
?估計是這些庫是個集合庫,使用Visual Studio較高版本開發的C++應用程序在發布時都要打包帶上。
? ? ? ?關于如何獲取這些以“api-ms-win”開頭的dll庫,到網上搜索了一下,有人在微軟的技術論壇中問過UCRT通用運行時庫的問題,如下:
Missing API DLL API STUB Set for Windowshttps://social.technet.microsoft.com/Forums/windows/en-US/327da89c-9d1c-4dca-9371-9771eabc3df9/missing-api-dll-api-stub-set-for-windows?forum=win10itprogeneral評論區中有人回復,可以參照下面這篇文章中的說明:
Introducing the Universal CRThttps://devblogs.microsoft.com/cppblog/introducing-the-universal-crt/其中下面一段話講到了如何去獲取the Universal CRT系統通用運行時庫,如下所示:
?于是這才知道,這些以api-ms-win-開頭多個dll庫叫做UCRT通用運行時庫。
6、如何查看軟件依賴了哪些C/C++運行時庫?
? ? ? ?當前軟件到底依賴了哪些C/C++運行時庫,可以直接在開發著的機器上將軟件運行起來,然后使用Process Exploer工具查看軟件進程加載的dll庫列表,就能看到了,比如:
?當然,也可以使用dumpbin工具將軟件所有模塊的依賴庫打印出來,也能找到依賴哪些運行時庫。具體如何使用dumpbin查看庫依賴關系,可以查看我之前寫的文章:
將dumpbin從Visual Studio中摳出來,并使用dumpbin查看exe和dll庫的依賴關系https://blog.csdn.net/chenlycly/article/details/135483516? ? ? ?如果程序中使用了多個版本的Visual Studio編譯的模塊,則需要把這些Visual Studio版本對應的運行時庫都帶上的。比如有些模塊是Visual Studio 2010編譯出來的,則會依賴msvcr100.dll和msvcp100.dll;有些模塊是Visual Studio 2017編譯出來的,則會依賴msvcp140.dll和vcruntime140.dll等庫。在發布版本時需要將這些依賴的dll庫都帶上。
? ? ? ?對于以api-ms-win-開頭多個dll庫UCRT通用運行時庫,可以先到官網上搜索Windbg,然后通過Windows SDK去安裝Windbg,然后在Windbg的安裝路徑中就能找到這些通用運行時庫,比如我本機的安裝目錄C:\Program Files (x86)\Windows Kits\10\Redist\10.0.17763.0\ucrt\DLLs中可以找到,如下所示:(可以在Windbg安裝目錄中以api-ms-win為關鍵字搜索,找到具體的路徑)
?7、將軟件從32位升級到64位后,要使用64位UCRT通用運行時庫
? ? ? ?最近將軟件從32位升級到64位,要將打包的運行時庫都換成64位的,比如msvcp140.dll、vcruntime140.dll等庫路徑,可以在開發者的機器上將64位軟件運行起來,然后使用Process Explorer工具查看這些庫的路徑:
到路徑中將dll庫拷貝到項目中即可。
? ? ? ?但對于以api-ms-win-開頭多個UCRT通用運行時庫,因為包含了多個dll庫,要將所有的dll庫都拷貝上,不好使用Process Explorer工具查看,可以到Windbg安裝路徑中整體拷貝x64版本UCRT即可。比如我本機的安裝目錄:
C:\Program Files (x86)\Windows Kits\10\Redist\10.0.17763.0\ucrt\DLLs
可以在這個路徑中找到,如下所示:(可以在Windbg安裝目錄中以api-ms-win為關鍵字搜索,找到具體的路徑)
?該路徑下有x86和x64兩個版本,分別對應32位和64位,我們拷貝x64版本即可。
8、發布軟件時未打包C/C++運行時庫的項目問題實例
? ? ? ?某天同事在調試使用瑞芯微主控CPU芯片的嵌入式設備(嵌入式設備使用的是Android系統)時,需要在PC上使用瑞芯微提供的一個工具軟件去遠程配置圖像質量參數,但這個工具啟動時會報錯,無法運行,如下所示:
?同事找到我,讓我幫他們看看是怎么回事,看能否讓這個工具盡快跑起來。經排查,瑞芯微提供的工具軟件包沒有將依賴的運行時庫msvcr120.dll和msvcp120.dll一起帶上,如下:
?正好同事的電腦上沒有這兩個庫,所以啟動報錯。瑞芯微是做硬件芯片的,可能軟件這塊不專業,這點也可以理解。
? ? ? ?這個問題的詳細排查過程,可以查看我之前寫的文章:
使用Dependency Walker和Process Explorer排查瑞芯微工具軟件RKPQTool.exe啟動報錯問題https://blog.csdn.net/chenlycly/article/details/135229025? ? ? ?另一個與C/C++運行時庫相關的實例,可以查看我的文章:
使用Process Explorer和Dependency Walker排查程序啟動時缺少ucrtbase.dll等運行時庫以及報0xC000007B錯誤https://blog.csdn.net/chenlycly/article/details/135483683