创建(和链接)库时的符号解析

时间:2014-07-28 09:07:54

标签: c++ linker operating-system shared-libraries

假设a.cc定义了一个使用f_a()中定义的函数f_b()的函数b.cc。从a.ccb.cc我创建了一个动态库libdynamic.so

假设文件main.cc使用f_a,我按如下方式编译:

g++ -o main main.cc -ldynamic

动态链接器如何将f_a(以及随后的f_b)的定义带入可执行文件? f_alibdynamic.so的定义是否已使用f_b解决?或者动态链接器还将在运行时解析此(内部)依赖关系?

2 个答案:

答案 0 :(得分:1)

由于您使用的是共享库(*.so),因此将 定义带入可执行文件。它保留在库本身并在运行时解析,这就是为什么如果删除共享库,程序将无法正常运行。

另一方面,在构建库时,必须解析库中的所有内部符号(在您的示例中为f_af_b)。从编译过程中可以看出这一点:

g++ -fPIC -c a.cc
g++ -fPIC -c b.cc
g++ -shared -Wl,-soname,libdynamic.so -o libdynamic.so a.o b.o

在最后阶段,g++调用链接器(ld)来链接f_a.of_b.o。实际上,您可以(可能)直接调用链接器:

ld -shared -soname=libdynamic.so -o libdynamic.so a.o b.o

如果您仍然对整个过程及其所有血腥细节感到好奇,请参阅以下文章:Linkers and Loaders, by Sandeep Grover

答案 1 :(得分:0)

基本上,动态库在运行时与可执行文件链接(即运行./main时)。编译器将负责在运行时解决依赖项。如果要通过nm命令检查依赖关系是否已解决。 'nm'命令提供的默认信息是 -

  1. 符号的虚拟地址
  2. 描述符号类型的字符。如果字符是小写,则符号是本地的,但如果字符是大写,则符号是外部的
  3. 符号名称
  4. 了解更多信息nm

    编译完程序后,只需执行nm exefilename(我想你的nm main)。