假设a.cc
定义了一个使用f_a()
中定义的函数f_b()
的函数b.cc
。从a.cc
和b.cc
我创建了一个动态库libdynamic.so
。
假设文件main.cc
使用f_a
,我按如下方式编译:
g++ -o main main.cc -ldynamic
动态链接器如何将f_a
(以及随后的f_b
)的定义带入可执行文件? f_a
中libdynamic.so
的定义是否已使用f_b
解决?或者动态链接器还将在运行时解析此(内部)依赖关系?
答案 0 :(得分:1)
由于您使用的是共享库(*.so
),因此将 定义带入可执行文件。它保留在库本身并在运行时解析,这就是为什么如果删除共享库,程序将无法正常运行。
另一方面,在构建库时,必须解析库中的所有内部符号(在您的示例中为f_a
和f_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.o
和f_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'命令提供的默认信息是 -
了解更多信息nm。
编译完程序后,只需执行nm exefilename
(我想你的nm main
)。