[英]dll linking static library - unresolved linker symbols from unused functions
我有一個提供許多功能的靜態庫staticLibA.lib
。 其中一些需要該庫中未提供的某些外部函數。
另外,我定義了一個動態庫dynLib.dll
,該庫使用某些靜態庫函數,但沒有一個函數需要上述外部函數。
但是,如果我鏈接動態庫,盡管沒有必要使用外部符號,但仍然得到了無法解析的外部符號。
編譯器是否應該僅從目標所需的靜態庫中選擇功能?
這是一個小例子
staticLib.lib:
// staticLib_fileA.c
extern void extLibFunction();
void slib_funcA(){
extLibFunction();
// some stuff
}
// staticLib_fileB.c
void slib_funcB(){
// some stuff
}
dynLib.dll
// dynLib.c
void dyn_func(){
slib_funcB();
// some stuff
}
dynLib.dll
的編譯/鏈接帶來了未解決的符號extLibFunction
:
staticLib.lib(staticLib_fileA.obj) : error LNK2001: unresolved external symbol extLibFunction
有辦法解決嗎? 一些編譯器設置要求僅鏈接實際所需的符號。 解決方法是一些虛擬的實現,但是我更喜歡某種方式,僅當lib用戶需要這些部分時才強制他做一些事情
與靜態庫不同,DLL不能包含未解析的符號(引用)。 DLL允許二進制文件在運行時訪問所有符號,甚至不需要其中的一些。 庫由.o文件制成。 庫中的某些.o文件可能包含程序中未使用的符號。 在鏈接時,只要您不需要這些未解析的符號或.o文件中包含未解析符號的任何其他符號,您的靜態庫就可以具有未解析的符號。 使用DLL,事情就不一樣了,即使您的程序不需要它們,也必須在鏈接時解析所有引用。
看來,由於fileB.obj
中的其他功能導致了fileA.obj
依賴性,因此目標文件總體上彼此具有依賴性。
因此,即使使用此依賴關系的函數永遠不會在鏈接的二進制文件中被調用(或者在dll:情況下被導出),甚至也不會在fileB
被調用,也必須滿足外部依賴關系。
如果啟用了“功能級別鏈接”和“ Comdat折疊”,這似乎是正確的。
Raymond Chen在一系列有關鏈接原理的博客文章中解釋了為什么這樣做是正確的:
https://devblogs.microsoft.com/oldnewthing/tag/linker
事實證明,即使采用了先進的技術(如上面提到的),第一步也是經典的方法,必須解決所有符號,即使隨后的優化將再次去除這些符號。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.