简体   繁体   English

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

[英]dll linking static library - unresolved linker symbols from unused functions

I have a static library staticLibA.lib that provides a number of functions. 我有一个提供许多功能的静态库staticLibA.lib some of them require some external functions that are not provided within this library. 其中一些需要该库中未提供的某些外部函数。

Additionally i define a dynamic library dynLib.dll that uses some of the static libraries functions, but none of the functions that require the mentioned external functions. 另外,我定义了一个动态库dynLib.dll ,该库使用某些静态库函数,但没有一个函数需要上述外部函数。

But if i link the dynamic library I get unresolved external symbols despite the fact that they should not be necessary. 但是,如果我链接动态库,尽管没有必要使用外部符号,但仍然得到了无法解析的外部符号。

Should not the compiler only select the functions from the static lib that the target does require? 编译器是否应该仅从目标所需的静态库中选择功能?

here a little example 这是一个小例子

staticLib.lib: 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.dll

// dynLib.c

void dyn_func(){
  slib_funcB();
  // some stuff
}

the compilation/link of dynLib.dll brings the unsolved symbol extLibFunction : dynLib.dll的编译/链接带来了未解决的符号extLibFunction

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

Is there some way around this? 有办法解决吗? some compiler settings that told to just link the actual required symbols. 一些编译器设置要求仅链接实际所需的符号。 A work around is some dummy implementation, but I would prefer some way that only forces the user of the lib to do something if he needs these parts 解决方法是一些虚拟的实现,但是我更喜欢某种方式,仅当lib用户需要这些部分时才强制他做一些事情

Unlike static libraries, DLLs can not have unresolved symbols(references). 与静态库不同,DLL不能包含未解析的符号(引用)。 A DLL allows a binary to access all of the symbols at runtime, even some of them were not needed. DLL允许二进制文件在运行时访问所有符号,甚至不需要其中的一些。 A library is made from .o files. 库由.o文件制成。 Some of these .o files from a library might contain symbols that are not used in your program. 库中的某些.o文件可能包含程序中未使用的符号。 At link time, your static library can have unresolved symbols as long as you do not need these unresolved symbols or any other symbol from a .o file which contains unresolved symbols. 在链接时,只要您不需要这些未解析的符号或.o文件中包含未解析符号的任何其他符号,您的静态库就可以具有未解析的符号。 With DLL, the thing is not the same and you must resolve all references at link time, even if your program doesn't need them. 使用DLL,事情就不一样了,即使您的程序不需要它们,也必须在链接时解析所有引用。

It seems that the object files at a whole have dependencies at each other because of other functions within fileB.obj that leads to dependency of fileA.obj . 看来,由于fileB.obj中的其他功能导致了fileA.obj依赖性,因此目标文件总体上彼此具有依赖性。

And because of this, also the external dependency has to be fullfilled, even if the function that uses this dependency never gets called (or in case of dll: gets exported) in the linked binary and not even gets called in fileB . 因此,即使使用此依赖关系的函数永远不会在链接的二进制文件中被调用(或者在dll:情况下被导出),甚至也不会在fileB被调用,也必须满足外部依赖关系。

This seems to be even true if "function level linking" and "Comdat Folding" is enabled. 如果启用了“功能级别链接”和“ Comdat折叠”,这似乎是正确的。

Why this is true is explained by Raymond Chen in a series of blog articles around the principle of linking: Raymond Chen在一系列有关链接原理的博客文章中解释了为什么这样做是正确的:

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

As it turns out, even with advanced techniques (like the above mentioned) the first step is the classical approach that has to get all its symbols resolved, even if the optimizing afterwards will strip these symbols again. 事实证明,即使采用了先进的技术(如上面提到的),第一步也是经典的方法,必须解决所有符号,即使随后的优化将再次去除这些符号。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM