linux 动态库 静态库 函数覆盖

本文讨论了linux动态库  静态库中函数的覆盖问题。

测试目的:

同名函数,分别打成动态库libdync_lib.so与静态库libstatic_lib.a,并把libstatic_lib.a打到另一个动态库libapi.so中,

在可执行程序中分别连接libdync_lib.so与libapi.so,此时到底调用的是哪个库中的函数?

测试结论:

不同库中的同名函数会被覆盖,后链接的库中的同名函数会被先前库覆盖。

测试方法:

static_lib.h

 1 void print(); 

static_lib.cpp

1 #include <cstdio.h>
2 #include "static_lib.h"
3 
4 void print()
5 {
6     printf("i am static print
");
7 }

dync_lib.h

 1 void print(); 

dync_lib.cpp

 #include <cstdio.h>
 #include "dync_lib.h"
 
 void print()
{
    printf("i am dync print
");
 }

api.h

void func();

api.cpp

1 #include "static_lib.h"
2 
3 void func()
4 {
5     print();
6 }

main.cpp

#include <api.h>

int main()
{    
      func();
      print();
return 0;        
}

制作libdync_lib.so动态库

g++ dync_lib.cpp -shared -fPIC -o libdync_lib.so

制作libstatic_lib.a静态库

g++ -c static_lib.cpp -share -fPIC -o static_lib.o

ar crv libstatic_lib.a static_lib.o

制作libapi.so动态库,其依赖静态库libstatic_lib.a

g++ api.cpp -shared -fPIC -o libapi.so -lstatic_lib

有三种方式生成可执行程序

1、g++ main.cpp -lapi -o main

2、g++ main.cpp -lapi -ldync_lib -o main

3、g++ main.cpp -ldync_lib -lapi -o main

每种方式都能执行成功,但输出不一样,

1、2执行时,输出一致:

i am static print

3执行时,输出;

i am dync print

下面分析原因:

1、第一种方式中,main.cpp中只包含了 api.h,而api.h中并没有定义print函数,那么main中怎么找到了该函数并且调用成功了呢?

因为,生成libapi.so时连接了libstatic_lib.a,而其中包含print,也就是说,静态库中的函数符号都会被打到动态库中,所以main能找到print函数的实现,来自libstatic_lib.a。

2、后2种方式中,只是额外链接libdync_lib.so,但链接的顺序不同。从结果中看,程序正常执行。

第二种方式调用的是libstatic_lib.a中的print函数,对比发现,第三种调用的是libdync_lib.so中的print。

也就是说,根据链接的顺序,先被链接的库中的符号(函数)会覆盖后面库中的同名符号。

原文地址:https://www.cnblogs.com/candl/p/9564975.html