@
3dwelcome 关键不在于-rdynamic ,
而是多个.so 之间或者.so 和可执行程序之间有相同的符号,最简单的构造方式就是链接相同的.a 或者编译进去相同的源文件。当项目结构复杂的时候除非强制依赖库全部用共享库,否则很难保证符号不重复。
libtest_c.so 的时候,不-ltest_a 倒是可以,但是这里的 sample 比较简单。如果这么做的话有两个前提
1. test_a 要编译成动态库
2. test_b 要把
libtest_a.so dlopen 进来。(意味着大型项目中可执行程序需要手动并按顺序把所有依赖的动态库 dlopen 进来)
如果不按上述方法做就可能碰到
https://www.owent.net/JqRzQ#comment-448 提到的问题。当然还有一种方法是链接选项里加上不裁剪未使用的符号,但是这样很会影响 LTO 。(不考虑每个模块需要手动精细地控制的情况)
另:我 blog 里的例子, b.cpp:18 改成 void* handle = dlopen("./
libtest_c.so", RTLD_NOW|RTLD_GLOBAL);
编译选项改成:
gcc -O0 -g -ggdb a.cpp -o libtest_a.a -c -fPIC -rdynamic
gcc -O0 -g -ggdb b.cpp -o test_b -fPIC -ldl -L$PWD -ltest_a -lstdc++ -rdynamic
gcc -O0 -g -ggdb c.cpp -o
libtest_c.so -shared -fPIC -L$PWD -ltest_a -lstdc++ -rdynamic
执行结果如下:
foo_class::foo_class(), this-> 0x602068
&foo_class::_ = 0x602068, foo_class::_.m = 1010
foo_class::foo_class(), this-> 0x602068
&foo_class::_ = 0x602068, foo_class::_.m = 110
foo_class::~foo_class(), this-> 0x602068
foo_class::~foo_class(), this-> 0x602068
我本地环境是 CentOS 7, GCC 4.8.5