多个链接库含有同名函数怎么处理

TLDR

.o目标文件编译期报错
.a静态库文件
 如果只有同名函数,编译期正常,运行时调用先链接的
 如果后链接的.c源码文件有独有函数,不管先链接的有没有独有函数,编译报与链接.o相同的错
 如果先链接的.c源码文件有独有函数,则正常链接运行先链接的
.so动态库文件编译期正常,运行时调用先链接的

前期基础

动态库静态库基础概念

同名函数测试

  • 测试准备
// test1.c 和 test2.c (代码相同)
#include <stdio.h>

void test() {
    printf("[test same func name] %s: %s\n", __FILE__, __func__);
}
// test4.c 有独有函数lalala
#include <stdio.h>

void test() {
  printf("[test same func name] %s: %s\n", __FILE__, __func__);
}

void lalala() {
  printf("[test same func name] lalala\n");
}
// test3.c 也有独有函数hehehe
#include <stdio.h>

void test() {
  printf("[test same func name] %s: %s\n", __FILE__, __func__);
}

void hehehe() {
  printf("[test same func name] hehehe\n");
}
// main.c 只调用同名函数test
extern void test();
int main() {
  test();
}
// main_la.c 增加调用test4独有函数
extern void test();
extern void lalala();
int main() {
  test();
  lalala();
}
// main_he.c 增加调用test3独有函数
extern void test();
extern void lalala();
extern void hehehe();
int main() {
  test();
  lalala();
  hehehe();
}
  1. .o目标文件:将包含同名函数的目标文件进行链接,如果其在同一个命名空间中,编译期会报multiple definition错误
gcc -c ./test1.c
gcc -c ./test2.c
gcc -o main ./test1.o ./test2.o ./main.c
# 编译报错
test2.o:在函数‘test’中:
test2.c:(.text+0x0): `test'被多次定义
test1.o:test1.c:(.text+0x0):第一次在此定义
collect2: error: ld returned 1 exit status
  1. .a静态库文件:将包含同名函数的目标文件分别编译成静态库,按顺序链接,编译正常,运行输出先链接的函数结果。
gcc -c ./test1.c
gcc -c ./test2.c
ar crv libtest1.a test1.o
ar crv libtest2.a test2.o
gcc -L. ./main.c -ltest1 -ltest2 -o main
./main
# 运行正常
[test same fun name] test1.c: test
# 加编译参数-Wl,--verbose重新编译可执行文件查看原因
gcc -L. ./main.c -ltest1 -ltest2 -o main -Wl,--verbose
# 看到只链接了libtest1.a背后的test1.o文件,同时存在动态库和静态库时,优先链接动态库
...
试图打开 ./libtest1.so 失败
试图打开 ./libtest1.a 成功
(./libtest1.a)test1.o
试图打开 ./libtest2.so 失败
试图打开 ./libtest2.a 成功
...
# 如果使用编译参数-Wl,--whole-archive链接libtest1.a和libtest2.a
gcc -L. ./main.c -Wl,--whole-archive -ltest1 -ltest2 -Wl,--no-whole-archive -o main
# 编译报错
./libtest2.a(test2.o):在函数‘test’中:
test2.c:(.text+0x0): `test'被多次定义
./libtest1.a(test1.o):test1.c:(.text+0x0):第一次在此定义
collect2: error: ld returned 1 exit status

4..a静态库文件后链接的库有独有函数:编译报与链接.o相同的错。

gcc -c ./test4.c
ar crv libtest4.a test4.o
gcc -L. ./main_la.c -ltest1 -ltest4 -o main_la
# 编译报错
./libtest4.a(test4.o):在函数‘test’中:
test4.c:(.text+0x0): `test'被多次定义
./libtest1.a(test1.o):test1.c:(.text+0x0):第一次在此定义
collect2: error: ld returned 1 exit status
# 两个文件都有独有文件也会报错
gcc -c ./test3.c
ar crv libtest3.a test3.o
gcc -L. ./main_he.c -ltest3 -ltest4 -o main_he
# 编译报错
./libtest4.a(test4.o):在函数‘test’中:
test4.c:(.text+0x0): `test'被多次定义
./libtest3.a(test3.o):test3.c:(.text+0x0):第一次在此定义
collect2: error: ld returned 1 exit status

5..a静态库文件先链接的库有独有函数:正常编译运行。

gcc -L. ./main_la.c -ltest4 -ltest1 -o main_la
LD_LIBRARY_PATH=./ ./main_la
[test same func name] ./test4.c: test
[test same func name] lalala
  1. .so动态库文件:将包含同名函数的源文件分别编译成动态库,按顺序链接,编译正常,运行输出先链接的函数结果。符号会以第一个查找到的为准(Symbols are resolved on a first match basis)。
gcc -shared -fPIC -o libtest1.so test1.c
gcc -shared -fPIC -o libtest2.so test2.c
gcc -L. ./main.c -ltest1 -ltest2 -o main -Wl,--verbose
# 查看链接过程
试图打开 ./libtest1.so 成功
-ltest1 (./libtest1.so)
试图打开 ./libtest2.so 成功
-ltest2 (./libtest2.so)
LD_LIBRARY_PATH=./ ldd main
# 查看链接结果只链接了test1.so
    linux-vdso.so.1 =>  (0x00007ffcc78c3000)
    libtest1.so => ./libtest1.so (0x00007f873a8f7000)
    libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f873a52d000)
    /lib64/ld-linux-x86-64.so.2 (0x00007f873aaf9000)
# 运行结果是test1中函数
LD_LIBRARY_PATH=./ ./main 
[test same fun name] test1.c: test

7..so动态库文件后链接的库有独有函数:同名函数会使用先链接的。

// main.c 增加调用test4独有函数
extern void test();
extern void lalala();
int main() {
  test();
  lalala();
}
# 编译test4.so和main,ldd查看链接还是只链接了test1
gcc -shared -fPIC -o libtest4.so test4.c
gcc -L. ./main.c -ltest1 -ltest4 -o main
ldd ./main
    linux-vdso.so.1 =>  (0x00007ffe127fd000)
    libtest1.so => not found
    libtest4.so => not found
    libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f345357b000)
    /lib64/ld-linux-x86-64.so.2 (0x00007f3453945000)
# 运行结果是test1中函数
LD_LIBRARY_PATH=./ ./main 
[test same func name] test1.c: test
[test same func name] lalala

8..so动态库文件都有独有函数:同名函数使用先链接的。

# 编译test3.so和main,ldd查看链接,链接了test3和test4
gcc -shared -fPIC -o libtest3.so test3.c
gcc -L. ./main.c -ltest3 -ltest4 -o main
ldd ./main
    linux-vdso.so.1 =>  (0x00007fff4cfbb000)
    libtest3.so => not found
    libtest4.so => not found
    libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f5523437000)
    /lib64/ld-linux-x86-64.so.2 (0x00007f5523801000)
# 运行结果是test3中函数
LD_LIBRARY_PATH=./ ./main 
[test same func name] test3.c: test
[test same func name] lalala
[test same func name] hehehe
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,204评论 6 506
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,091评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,548评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,657评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,689评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,554评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,302评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,216评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,661评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,851评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,977评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,697评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,306评论 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,898评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,019评论 1 270
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,138评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,927评论 2 355

推荐阅读更多精彩内容