2011-12-26 40 views
2

我對鏈接過程幾乎一無所知,當我試圖開始一個新項目或添加一個新庫時,它幾乎總是會遇到阻礙。每當我尋找修復這些類型的錯誤時,我都會發現有類似問題的人,但很少有任何修復。C++鏈接器問題,是否有一種通用的方法來解決這些問題?

有沒有找到問題出現的一般方法,並修復它?

我正在使用visual studio 2010,並將我的庫靜態鏈接到我的程序中。我的問題似乎總是來自與LIBCMT(D).lib,MSVCRT(D).lib和其他一些雙重定義某些功能的庫的衝突。如果它很重要,我的意圖是避免使用「託管」C++。

+2

幾乎完全沒有關於什麼東西,並要求一個普遍的方式來排除故障...似乎很明顯,最好的藥物是預防在這裏。瞭解其工作原理,以便您可以使用最佳做法,防止出現錯誤並排除故障。 – tenfour 2011-12-26 20:42:40

+0

沒關係,只要讀一下它就可以了。我想對它說很多可恨的話。就像連接器在今天和這個時代不應該存在一樣。但我猜我會填塞它。不過,我至少明白這個概念以及他們現在應該做的事情。 – 2011-12-26 21:09:38

+0

[連接器快速入門](http://blogs.msdn.com/b/oldnewthing/archive/2009/10/12/9905953.aspx)。 – 2011-12-26 21:17:13

回答

2

如果您的錯誤與LIBCMT(D).lib等有關,通常取決於您使用與您的CRT版本不同的庫進行鏈接的事實。唯一真正的解決方法是使用爲相同版本的CRT編譯的庫(常常因爲這個原因有「調試」和「版本」版本),或者(如果您絕望)更改CRT版本你用來匹配圖書館的一個。

幕後發生的事情是,你的程序和你的程序庫都需要CRT功能正常工作,並且每個程序都已經鏈接到它。如果他們鏈接到相同版本的它沒有什麼不好發生(鏈接器認爲它是相同的,並沒有抱怨),否則有多個相同的函數相沖突的實現,所以鏈接器不知道哪些是適合的哪些對象模塊(以及由於它們可能不是二進制兼容的,兩個CRT的內部數據結構將不兼容)。

+0

就是這樣。我將其中一個庫設置爲靜態鏈接到STD庫,而不是使用共享庫。因此,所有從libcmt定義的多個東西。謝謝! – 2011-12-26 21:21:04

+0

@Clairvoire:這是靜態庫的常見問題。這就是爲什麼當你必須安裝例如提升你必須爲每個可用的CRT生成靜態庫(並且在VC++ 2003中有用於單線程靜態,多線程靜態,多線程DLL的所有調試/發佈組合),這是相當不方便的。 – 2011-12-26 21:24:48

1

您提到的特定鏈接錯誤(使用LIBCMT(D).lib,MSVCRT(D).lib庫)與程序中模塊/庫之間的代碼生成選項中的衝突有關。

當您編譯模塊時,編譯器會自動在生成的.obj中插入一些對運行時庫(LIBCMT & MSVCRT)的引用。現在,每種代碼生成模式都有一個這樣的庫版本(我指的是配置屬性 - > C/C++ - >代碼生成 - >運行時庫)中的選項。所以如果你有兩個模塊用不同的模式編譯,每個模塊都會引用一個不同版本的庫,鏈接器會試圖包含這兩個模塊,當然會有重複的符號,因爲基本上所有的符號都是相同的在這些庫中,只有它們的實現有所不同。

該解決方案分爲三部分。首先,確保項目中的所有模塊使用相同的模式。其次,如果你有項目之間的依賴關係,他們都必須使用相同的模式。第三,如果您使用第三方庫,您必須知道它們使用哪種模式(並採用它)或能夠使用所需的模式重新編譯它們。

最後一個是最困難的。有時候,庫會預先編譯,並不總是提供者提供關於所用模式的信息。更糟的是,如果您使用的是多個第三方庫,則它們可能存在衝突模式。在這些情況下,你沒有比試驗錯誤更好的選擇。

另請注意,每個Visual Studio版本都有自己的一組運行時庫,因此使用第三方庫時,必須使用與您使用的Visual Studio相同版本編譯的版本。如果提供者不提供它,你唯一的選擇是重新編譯自己。