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