共享库:
1.概念
- 共享库就是动态链接库,是在程序运行的时候加载的函数库。详细介绍:https://blog.csdn.net/Lincoln_cz/article/details/81982908
2.生成一个共享库
- 代码结构:
实现一个四则运算的共享库:
├── add.cpp
├── common.h
├── dev.cpp
├── main.cpp
├── mul.cpp
└── sub.cpp
common.h文件:
#ifndef _COMMONH_
#define _COMMONH_
int add(int a,int b);
int sub(int a,int b);
int mul(int a,int b);
int dev(int a,int b);
#endif
add.cpp文件:
int add(int a,int b){
return (a+b);
}
sub.cpp文件:
int sub(int a,int b){
return (a-b);
}
mul.cpp文件:
int mul(int a,int b){
return (a*b);
}
dev.cpp文件:
int dev(int a,int b){
return (a/b);
}
main.cpp文件:
#include <iostream>
#include "common.h"
using namespace std;
int main(){
cout << "begin():" <<endl;
cout << "test add:"<<add(4,1)<<endl;
cout << "test sub:"<<sub(4,1)<<endl;
cout << "test mul:"<<mul(4,1)<<endl;
cout << "test dev:"<<dev(4,1)<<endl;
return 0;
}
- 步骤:
第一步:将函数库代码只编译不链接,生成与位置无关的.o文件
#输入命令:
g++ -fPIC -c add.cpp sub.cpp mul.cpp dev.cpp
说明:其中,fPIC 作用于编译阶段,告诉编译器产生与位置无关代码(Position-Independent Code),则产生的代码中,没有绝对地址,全部使用相对地址,故而代码可以被加载器加载到内存的任意位置,都可以正确的执行。这正是共享库所要求的,共享库被加载时,在内存的位置不是固定的。
结果:
├── add.cpp
├── add.o
├── common.h
├── dev.cpp
├── dev.o
├── main.cpp
├── mul.cpp
├── mul.o
├── sub.cpp
└── sub.o
第二步:生成共享库
#输入命令:
g++ -shared -Wl,-soname,libmycal.so.1 add.o sub.o mul.o dev.o -o libmycal.so.1.10
说明:-shared表示生成共享库;-Wl表示告诉编译器将后面的参数传递给链接器,于Wl来说,它的参数分割是用","。-soname是告诉编译器共享库的soname是libmycal.so.1;生成的目标文件是libmycal.so.1.10,是共享库的realname。这里我们对soname和realname进行说明:realname是动态库文件的真实的名字,记录了共享库的主版本和次版本号,本例中libmycal.so.1.10,主版本号为1,次版本号为10;而soname只记录了共享库的主版本号,本例中的soname为libmycal.so.1,只记录了主版本号1(soname一般是个软链接,指向realname)。
结果:生成共享库libmycal.so.1.10。
├── add.cpp
├── add.o
├── common.h
├── dev.cpp
├── dev.o
├── libmycal.so.1.10
├── main.cpp
├── mul.cpp
├── mul.o
├── sub.cpp
└── sub.o
若此时利用生成的共享库与自己编写的程序一起编译,则会报错,例如我们main.cpp与共享库一起编译:
#输入命令:
g++ main.c libmycal.so.1.10 -o app
结果:生成目标程序app
├── add.cpp
├── add.o
├── app
├── common.h
├── dev.cpp
├── dev.o
├── libmycal.so.1.10
├── main.cpp
├── mul.cpp
├── mul.o
├── sub.cpp
└── sub.o
此时执行app,会报错:
./app: error while loading shared libraries: libmycal.so.1: cannot open shared object file: No such file or directory
原因:有了共享库,但没有加入系统路径。
接着我们查看app所依赖的库:
#输入命令:
ldd app
结果:
linux-vdso.so.1 (0x00007fff11b9c000)
libmycal.so.1 => not found
libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f0a30697000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f0a302a6000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f0a2ff08000)
/lib64/ld-linux-x86-64.so.2 (0x00007f0a30c23000)
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f0a2fcf0000)
我们看到libmycal.so.1 => not found,即libmycal.so.1这个库系统没有找到
第三步:修改系统配置文件,将共享库为系统所共享
首先修改配置文件,将当前共享库路径加入配置文件
#输入命令:
sudo vi /etc/ld.so.conf
说明:ld.so.conf为系统共享库的配置文件,打开后将当前路径加入即可。
之后更新库:
#输入命令:
sudo ldconfig -v
结果:自动生成soname软连接,即下面的libmycal.so.1(指向realname)
├── add.cpp
├── add.o
├── app
├── common.h
├── dev.cpp
├── dev.o
├── libmycal.so.1 -> libmycal.so.1.10
├── libmycal.so.1.10
├── main.cpp
├── mul.cpp
├── mul.o
├── sub.cpp
└── sub.o
此时再执行app,可以得到结果:
begin():
test add:5
test sub:3
test mul:4
test dev:4
第四步:生成linkname
#输入命令:
ln -s libmycal.so.1.10 libmycal.so
libmycal.so为linkname,linkname相比soname和realname,没有记录库的版本号,一般用于makefile中,soname只记录主版本号,realname记录主版本和次版本。linkname和soname均指向realname。
link name(libmycal.so)->real name(libmycal.so.1.10)
so name(libmycal.so.1)->real name(libmycal.so.1.10)
网友评论