c - 链接共享库后符号丢失

标签 c gcc shared-libraries

考虑下面列出的两个文件:

文件a.c

extern int foovar;
int foobarize() {
    return foovar * foovar;
}

和文件b.c

int foovar = 10;

我编译静态库liba.a和共享库libb.so如下:

# liba.a
gcc -fPIC -c a.c -o a.o
ar cr liba.a a.o
ranlib liba.a

# libb.so
gcc -fPIC -c b.c -o b.o
gcc -fPIC -shared -Wl,-soname,libb.so -o libb.so b.o liba.a

请注意,a.c 中定义的函数 foobarize 存在于 liba.a 中,但它不存在于 libb.so 中。我可以通过发出 nm 程序来保证:

$ nm liba.a

a.o:
0000000000000000 T foobarize
                 U foovar
                 U _GLOBAL_OFFSET_TABLE_

$ nm libb.so
000000000020088c B __bss_start
000000000020088c b completed.6617
                 w __cxa_finalize@@GLIBC_2.2.5
0000000000000530 t deregister_tm_clones
00000000000005c0 t __do_global_dtors_aux
0000000000200650 t __do_global_dtors_aux_fini_array_entry
0000000000200880 d __dso_handle
0000000000200660 d _DYNAMIC
000000000020088c D _edata
0000000000200890 B _end
0000000000000630 T _fini
0000000000200888 D foovar
0000000000000600 t frame_dummy
0000000000200648 t __frame_dummy_init_array_entry
0000000000000640 r __FRAME_END__
0000000000200858 d _GLOBAL_OFFSET_TABLE_
                 w __gmon_start__
00000000000004d8 T _init
                 w _ITM_deregisterTMCloneTable
                 w _ITM_registerTMCloneTable
0000000000200658 d __JCR_END__
0000000000200658 d __JCR_LIST__
                 w _Jv_RegisterClasses
0000000000000570 t register_tm_clones
0000000000200890 d __TMC_END__

如何获取libb.so共享库中的foobarize函数?

最佳答案

您需要什么:

# force all symbols

gcc -fPIC -shared -Wl,-soname,libb.so -o libb.so b.o \
           -Wl,--whole-archive liba.a -Wl,--no-whole-archive

#force just a specific symbol

gcc -fPIC -shared -Wl,-soname,libb.so -o libb.so b.o \
           -u foobarize liba.a

为什么你需要它:

静态库是目标文件的简单集合。与一堆目标文件的一个主要区别如下:当需要解析 undefined symbol 时,会搜索库,并且仅链接实际定义该符号的目标文件。没有 undefined symbol ?没有搜索任何内容,也没有链接任何内容。为了覆盖此默认行为,GNU 链接器实现了 --whole-archive。大多数链接器实现 -u 来强制将特定符号视为未定义。

关于c - 链接共享库后符号丢失,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24232726/

相关文章:

mysql_fetch_fields 返回的长度与预期不同

c++ - 我的代码不适用于大数字

c++ - 预处理器指令应该在行首吗?

c - 多个 #ifndef 语句 - 应用哪一个

java - 如何处理我的库中任意用户提供的类型?

c++ - 无法通过函数为全局变量赋值(Linux 上的共享库注入(inject))

c - 打印堆栈指针与 backtrace() 打印输出

c - main.c 中定义的宏在另一个包含的文件中不可见

c++ - C++中的类接口(interface)继承

java - native 库,Java OpenAL 所需