繁体   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