g++编译动态链接库*.so调用另一个*.so的方法
1. 编译文件内容
包括四个文件,分别是:DemoTest.h、one.cpp、two.cpp。
DemoTest.h
#ifndef __DEMO_TEST_HEADER__ #define __DEMO_TEST_HEADER__ #include <iostream> using namespace std; void one(); void two(); #endif
one.cpp
#include "DemoTest.h" void one() { cout<< "call one() function." << endl; }
two.cpp
#include "DemoTest.h" void two() { cout << "call two() function." << endl; one(); cout << "call one in twofunction." << endl; }
2. *.so动态库的编译
编译命令:g++ one.cpp -fPIC -shared -o libone.so
这里把one.cpp编译生成的动态库是libone.so。
在two.cpp文件中调用one(),所以在编译要把libone.so加到编译文件中,命令如下:
g++ libone.so two.cpp -fPIC -shared -o libtwo.so
3. 动态库的连接
第二部分已经生成了一个动态链接库libtwo.so,现在我们创建一个程序来调用这个库文件。
main.cpp
#include "DemoTest.h" int main() { two(); return 0; }
这里需要注意的是main调用了libtwo.so 而 libtwo.so 调用了libone.so。所以在生成可执行文件的时候要把libone.so加到被编译中去。命令如下:
g++ main.cpp -L. -lone -ltwo -o main
这里生成的main为调用动态库的可执行文件。
4. 执行可执行程序
执行命令:./main
如果报错 ./main: error while loading shared libraries: libone.so: cannot openshared object file: No such file or directory
这是因为执行时找不到*.so库文件,最简单的方法是配置文件/etc/ld.so.conf中指定动态库搜索路径。可以通过编辑配置文件/etc/ld.so.conf来指定动态库的搜索路径,该文件中每行为一个动态库搜索路径。编辑完成之后,必须运行命令ldconfig使修改后的配置生效。
5. 编译参数含义
-shared该选项指定生成动态连接库(让连接器生成T类型的导出符号表,有时候也生成弱连接W类型的导出符号),不用该标志外部程序无法连接。相当于一个可执行文件。
-fPIC:表示编译为位置独立的代码,不用此选项的话编译后的代码是位置相关的所以动态载入时是通过代码拷贝的方式来满足不同进程的需要,而不能达到真正代码段共享的目的。
-L.:表示要连接的库在当前目录中。
-lxxxx:编译器查找动态连接库时有隐含的命名规则,即在给出的名字前面加上lib,后面加上.so来确定库的名称。