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



我有一个静态库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
}

丁利布.dll

// dynLib.c
void dyn_func(){
slib_funcB();
// some stuff
}

dynLib.dll的编译/链接带来了未解的符号extLibFunction

staticLib.lib(staticLib_fileA.obj) : error LNK2001: unresolved external symbol extLibFunction

有没有办法解决这个问题? 一些编译器设置告诉只链接实际所需的符号。 解决方法是一些虚拟实现,但我更喜欢某种方式,只在需要这些部分时才强制库的用户做某事

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

似乎整个目标文件彼此依赖,因为fileB.obj中的其他功能导致fileA.obj依赖。

正因为如此,还必须填充外部依赖项,即使使用此依赖项的函数永远不会在链接的二进制文件中被调用(或者在 dll 的情况下:被导出(,甚至不会在fileB中被调用。

如果启用了"功能级链接"和"Comdat Folding",这似乎是正确的。

为什么这是真的,Raymond Chen在一系列围绕链接原理的博客文章中进行了解释:

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

事实证明,即使使用高级技术(如上面提到的(,第一步也是必须解决其所有符号的经典方法,即使之后的优化将再次剥离这些符号。

最新更新