1 生成动态链接库
- 创建用于生成so文件的c源文件:testSo.c
#include "stdio.h"
#include "testH.h"
void vvprints(void)
{
printf("hello!!, this is from so file.\n");
}
- 使用gcc进行编译并生成so文件:
$ gcc testSo.c -fPIC -shared -o libtest.so
其中:
-fPIC :表示编译为位置独立的代码,不用此选项的话编译后的代码是位置相关的所以动态载入时是通过代码拷贝的方式来满足不同进程的需要,而不能达到真正代码段共享的目的。
-shared :该选项指定生成动态连接库(让连接器生成T类型的导出符号表,有时候也生成弱连接W类型的导出符号),不用该标志外部程序无法连接。相当于一个可执行文件
2 编写头文件
- 创建头文件testH.h:
extern "C" void vvprints(void);
这样做会产生下面的错误:
解决方法参考http://blog.sina.com.cn/s/blog_640531380102yj80.html:
第一种方法:在C++ 文件(testmain.cpp)中
extern "C"
{
#include"testH.h"
}
第二种方法:在头文件(testH.h)中
#ifdef __cplusplus
extern "C" {
#endif
void vvprints(void);
#ifdef __cplusplus
}
#endif
3 调用so文件
- testmain.cpp:
#include "testH.h"
using namespace std;
int main(void)
{
lccprints();
return 0;
}
- 将cpp文件与so文件链接并生成执行文件:先将so文件拷贝至/lib文件夹内:
$ sudo cp /home/vv/LinuxLearning/libtest.so /lib/
注意:若不进行这一步将会出现下面的错误:
解决方法参考:严慈善
- 再进行编译:
$ g++ testmain.cpp -ltest -o testmain
4 注
参考b站视频:BV1mp4y1k7Dh:
若采用
$ g++ testmain.cpp -o testmain
则报错:
/tmp/ccQn5dH7.o:在函数‘main’中:
testmain.cpp:(.text+0x5):对‘lccprints’未定义的引用
collect2: error: ld returned 1 exit status
意思是链接错误(ld错误),不是编译错误。因此需要告诉编译器去查找链接,加上-lxxx(xxx处是so文件名中的libxxx,因此此处为-ltest):
$ g++ testmain.cpp -ltest -o testmain
若出现:cannot fing -ltest
应改为:
$ g++ testmain.cpp -L. -ltest -o testmain
其中:
-L.:表示要连接的库在当前目录中
-ltest:编译器查找动态连接库时有隐含的命名规则,即在给出的名字前面加上lib,后面加上.so来确定库的名称
于是生成了名为testmain的可执行文件,最后在终端中通过./testmain执行该文件,有如下结果: