2012-03-15 49 views
2

當我需要在不同版本的MSVC中構建一些用於我的幾個項目中的第三方庫時,我通常會爲其 MSVC版本和兩個調試版本配置。這就是推動力所在,而這正是我們在我們整個人生中爲我們所做的一切。如何在我的項目中正確構建用於調試和發佈配置的第三方庫?

但是,我仍然沒有得到,爲什麼我不能像建立這個庫...什麼。我需要的只是函數原型和目標代碼,對吧?由於我靜態鏈接CRT,我沒有外部依賴。但是當我試圖將MSVC8下的Release版本與我在MSVC10下調試的項目鏈接起來時,我有這個煩人的「已定義」鏈接器錯誤,我們都非常討厭這個錯誤。

但是爲什麼?我是否可以在lib中「封裝」所有這些函數,而不要將它們導出,以便我的項目僅從lib中獲取所需的內容?爲什麼我可以在每個項目中鏈接libpng和zlib的預編譯版本?是的,他們不是使用MSVC構建的,但我仍然使用CRT的相同功能。那麼任何人都可以請深入解釋一下,或者分享一些關於這個問題的一些開明解釋的鏈接嗎?

回答

3

由於我靜態鏈接CRT,我沒有外部依賴

好吧,這不是真的,你有依賴性。在CRT的靜態版本上。調試或發佈,具體取決於您的構建設置。這是一種外部依賴性,鏈接器在圖書館被鏈接後粘合CRT。使用該庫的代碼也依賴於CRT。如果編譯設置不匹配,那麼鏈接器barfs。

通過構建DLL而不是靜態鏈接庫來隔離該依賴關係。您必須進一步確保導出的函數不會導致CRT依賴性。您無法從標準C++庫中返回C++對象,也無法返回指向需要由客戶端代碼發佈的對象的指針。即使是傳遞結構也很棘手,因爲它們的包裝是一個實現細節,但你通常會忽略它。一個很好的實例是COM自動化,它迫使您使用通用類型的子集。 Windows充斥着它們,所有這些服務器都可以與任何版本的編譯器或CRT一起工作。甚至任何語言。然而,這是有代價的,編寫這樣一個庫並不像在一個靜態庫中拋出一堆代碼那麼簡單或方便。

+0

不錯的答案! 「...鏈接器稍後黏合CRT,當庫鏈接時...」 - 是否有強制鏈接器鏈接到.lib中的CRT函數的方法?我可以將自己的代碼鏈接到,爲什麼我不能強制CRT鏈接? – Mikhail 2012-03-15 16:38:00

+1

這不是靜態.libs的工作方式。這是一個非常簡單的文件格式,只是一個.obj文件的集合。你強制鏈接器通過創建一個DLL鏈接CRT。 – 2012-03-15 16:55:09

相關問題