linux动态链接库编译和调用
2017-11-02 本文已影响0人
戴宏鹏
src/Person目录下有Person.h和Person.cpp文件,编译成动态链接库:
g++ Person.cpp -fpic -shared -o libPerson.so
生成文件:
libPerson.so
src/test目录下有main.cpp文件创建Person对象,查看源代码:
root@bogon:~/src/test# cat main.cpp
#include <iostream>
#include "Person.h"
using namespace std;
int main()
{
Person person;
cout << "test g++" << endl;
return 0;
}
-shared:该选项指定生成动态连接库(让连接器生成T类型的导出符号表,有时候也生成弱连接W类型的导出符号),不用该标志外部程序无法连接。相当于一个可执行文件
-fPIC:表示编译为位置独立的代码,不用此选项的话编译后的代码是位置相关的所以动态载入时是通过代码拷贝的方式来满足不同进程的需要,而不能达到真正代码段共享的目的。
root@bogon:~/src/test# g++ main.cpp -o main -I../Person -L../Person -lPerson
编译生成应用程序main,其中命令中
-L.:表示要连接的库在当前目录中
-lPerson:编译器查找动态连接库时有隐含的命名规则,即在给出的名字前面加上lib,后面加上.so来确定库的名称
root@bogon:~/src/test# ./main
./main: error while loading shared libraries: libPerson.so: cannot open shared object file: No such file or directory
root@bogon:~/src/test# export LD_LIBRARY_PATH=../Person
我们知道一个程序要想在内存中运行,除了编译之外还要经过链接和装入这两个步骤。当然linux中动态链接也是经过这三个过程。Linux 使用这个ld-linux.so*中的来装载(其实这只是一个链接)其他库。所以这个库必须放在linux中/lib下。对于其他,通常我们共享库放在/lib这个路径下,而且也是系统默认的搜索路径。
Linux共享库的搜索路径先后顺序:
1、编译目标代码时指定的动态库搜索路径:在编译的时候指定-Wl,-rpath=路径
2、环境变量LD_LIBRARY_PATH指定的动态库搜索路径
3、配置文件/etc/ld.so.conf中指定的动态库搜索路径
4、默认的动态库搜索路径/lib
5、默认的动态库搜索路径 /usr/lib
此处,我们使用了第2中方法来使用该动态库,先执行以下命令,设置LD_LIBRARY_PATH的值
root@bogon:~/src/test# ./main
Create Person
test g++
查看依赖:
root@bogon:~/src/test# ldd main
linux-vdso.so.1 => (0x00007ffdb78f6000)
libPerson.so => ../Person/libPerson.so (0x00007f094cde8000)
libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f094ca60000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f094c695000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f094c38c000)
/lib64/ld-linux-x86-64.so.2 (0x0000555b0b8b1000)
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f094c176000)
root@bogon:~/src/test#