簡體   English   中英

dll鏈接靜態庫-未使用函數中未解析的鏈接器符號

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM