dll链接静态库-未使用函数中未解析的链接器符号

时间:2019-09-12 13:17:59

标签: c++ c visual-studio visual-c++ linker

我有一个静态库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的用户时才强制他们做些事情

2 个答案:

答案 0 :(得分:0)

与静态库不同,DLL不能包含未解析的符号(引用)。 DLL允许二进制文件在运行时访问所有符号,甚至不需要其中的一些。 库由.o文件制成。库中的某些.o文件可能包含程序中未使用的符号。 在链接时,只要您不需要这些未解析的符号或.o文件中包含未解析的符号的任何其他符号,您的静态库就可以具有未解析的符号。使用DLL,事情就不一样了,即使您的程序不需要它们,也必须在链接时解析所有引用。

答案 1 :(得分:0)

似乎由于fileB.obj中的其他功能导致fileA.obj的依赖性,目标文件整体上彼此具有依赖性。

因此,即使使用该依赖关系的函数永远不会在链接的二进制文件中被调用(或在dll:情况下被导出),甚至也不会在{{ 1}}。

如果启用了“功能级别链接”和“ Comdat折叠”,这似乎是正确的。

雷蒙德·陈(Raymond Chen)在围绕链接原理的一系列博客文章中解释了为什么这样做是正确的。

https://devblogs.microsoft.com/oldnewthing/tag/linker

事实证明,即使采用了先进的技术(如上面提到的),第一步也是经典的方法,必须解决所有符号,即使随后的优化将再次去除这些符号。