在C++中,靜態庫A鏈接到動態庫B和C中。如果在B中定義的A中使用了類Foo,那麼C鏈接是否會使用Foo?靜態和動態庫鏈接
我認爲答案是肯定的,但是我現在遇到了一個xlc_r7問題,其中庫C說Foo是一個未定義的符號,就C而言。我的問題是庫C不使用引用它的類。這在Win32(VC6)和OpenVMS中鏈接。
這是鏈接器差異還是PBCAK?
新信息:
B依賴於C,但不是反之亦然。
我沒有使用/ OPT:REF鏈接在Windows上,它沒有問題的鏈接。
在C++中,靜態庫A鏈接到動態庫B和C中。如果在B中定義的A中使用了類Foo,那麼C鏈接是否會使用Foo?靜態和動態庫鏈接
我認爲答案是肯定的,但是我現在遇到了一個xlc_r7問題,其中庫C說Foo是一個未定義的符號,就C而言。我的問題是庫C不使用引用它的類。這在Win32(VC6)和OpenVMS中鏈接。
這是鏈接器差異還是PBCAK?
新信息:
B依賴於C,但不是反之亦然。
我沒有使用/ OPT:REF鏈接在Windows上,它沒有問題的鏈接。
當你靜態鏈接時,兩個模塊成爲一個。因此,當您編譯C並鏈接到它時,就好像您已將A的所有源代碼複製到C的源代碼中,然後編譯組合的源代碼。所以C.dll包含A,它通過Foo依賴於B。您需要將C鏈接到B的鏈接庫以滿足該依賴關係。
請注意,根據您的信息,這將創建B和C.
聽起來像它可能是連接器(LD/UNIX),作爲LD鏈接從左至右庫(即我使用的大多數版本) - 如果沒有在第一個的參考這是後面的要求,通常的技巧是將第一個庫(或任何所需的庫)追加到命令的末尾。
這是一個嘗試,看看....
雖然xlc的鏈接器很棘手,但是......從左到右的鏈接線大部分都能正常工作,但實際上,所有內容都被加載到內存中,然後完成圖形漫步以滿足鏈接。它比舊式鏈接更昂貴,但鏈接線不必訂購。它也以有趣的方式打破 – 2008-10-04 01:01:56
我不認爲這是問題,因爲1.我嘗試了不同的順序和2.Foo沒有被任何其他庫使用。 – Jake 2008-10-05 03:45:57
是對C您的鏈接線包括出口LIB對於B?如果是這樣,理查德建議它聽起來像一個訂購的東西。
另一個建議是查看是否有鏈接器選項忽略未引用的符號,如果C不需要A的功能。對於Microsoft鏈接器,這通過/ OPT:REF開關實現。
的唯一原因之間的循環依賴爲什麼C將不鏈接是編譯器認爲它確實需要的富象徵。
因爲C沒有引用Foo符號,所以鏈接器需要該符號必須有另一個原因。
我知道的唯一的其他原因是某種出口。我只知道Visual C++,所以我建議你在預處理的文件中搜索一些等效的__declspec(dllexport)
,並查看它生成的內容。
下面是我要做的:將預處理器輸出存儲在一個單獨的文件中,並搜索Foo的出現次數。要麼它會作爲導出出現,要麼被編譯器以某種方式引用。
如果不需要特定函數的定義,那麼在鏈接階段不會鏈接該庫。在你的情況下,由於foo的定義存在於庫B中,而不是庫C中。因此,在加載可執行文件時,庫C將不會加載到內存中。
但是看起來,你也在庫C中使用了foo()函數,因爲你正在得到相應的錯誤。
根據msdn,LINK默認刪除未引用的打包函數(就像您使用/ OPT:REF一樣)。 – xtofl 2008-10-04 18:49:20