Linux 动态链接库(.so)的使用
1. 背景
库:就是已经编写好的,后续可以直接使用的代码。
c++静态库:会合入到最终生成的程序,使得结果文件比较大。优点是不再有任何依赖。
c++动态库:动态库,一个文件可以多个代码同时使用内存中只有一份,节省内存,可以随主代码一起编译。缺点是需要头文件。
网友说:库就是除了main函数之外的其他代码,都可以组成库。
2. 只介绍动态库(工作中主要用动态库)
C++使用动态库比C语言使用动态库稍微麻烦点。
因为C++支持函数重载(参数变量个数不同、参数类型不同、类型修饰符不同const/not const等),都会使得C++对函数名进行重写,不方便根据函数名查找对应函数。
C++中可以使用extern关键字修饰对应的函数,表示函数名按照C言语分隔编译,不进行改写。(extern关键字另一个关键字修饰变量,表示变量在其他文件中已经定义。通常见于修饰全局变量)
3. 使用so文件需要的api
头文件 #include <dlfcn.h>

dlopen以指定的模式打开共享链接库。使用可以参考: http://man7.org/linux/man-pages/man3/dlopen.3.html
4. C++使用动态链接库实例
4.1 test.h
class Test{
public:
virtual int get();
virtual void set(const int num);
};
4.2 test.cpp
#include <iostream>
#include "test.h" int g_num = ; ///全局变量 int Test::get() { return g_num; }
void Test::set(const int num){ g_num = num; } #ifdef __cplusplus
extern "C" {
#endif Test* create(){ return new Test; } #ifdef __cplusplus
}
#endif
4.3 main.cpp
#include <iostream>
#include <dlfcn.h>
#include "test.h"
using namespace std; //声明函数指针
typedef Test* (*so_init)(); //定义插件类来封装,句柄用完后需要释放
struct Plugin{
void *handle;
Test *t; Plugin():handle(NULL), t(NULL) { }
~Plugin(){
if(t) { delete t; }
if (handle) { dlclose(handle); }
}
}; int create_instance(const char *so_file, Plugin &p){
//根据特定的模式打开so文件, 获取so文件句柄
//RTLD_NOW:需要在dlopen返回前,解析出所有未定义符号
//RTLD_DEEPBIND:在搜索全局符号前先搜索库内的符号,避免同名符号的冲突
p.handle = dlopen(so_file, RTLD_NOW | RTLD_DEEPBIND);
if (!p.handle) {
cout << "Cannot open library: " << dlerror() << endl;
return -;
} //根据字符串"create"读取库中对应到函数, 并返回函数地址,可以理解为一种间接的“反射机制”
so_init create_fun = (so_init) dlsym(p.handle, "create");
if (!create_fun) {
cout << "Cannot load symbol" << endl;
dlclose(p.handle);
return -;
} //调用方法, 获取类实例
p.t = create_fun(); return ;
} int main(){
Plugin p1;
Plugin p2; if ( != create_instance("./libtest_1.so", p1)
|| != create_instance("./libtest_2.so", p2)){
cout << "create_instance failed" << endl;
return ;
} p1.t->set(); //对库1中到全局变量进行设置
p2.t->set(); //对库2中到全局变量进行设置 //输出两个库中的全局变量
cout << "t1 g_num is " << p1.t->get() << endl;
cout << "t2 g_num is " << p2.t->get() << endl;
return ;
}
执行:
g++ -fPIC -shared test.cpp -o libtest_1.so
g++ -fPIC -shared test.cpp -o libtest_2.so
g++ -g -Wl,--no-as-needed -ldl main.cpp -rdynamic

Linux 动态链接库(.so)的使用的更多相关文章
- Linux动态链接库的创建与使用
Linux动态链接库的创建与使用1. 介绍 使用GNU的工具我们如何在Linux下创建自己的程序函数库?一个“程序函数库”简单的说就是一个文件包含了一些编译好的代码和数据,这些编译好的代码和数 ...
- linux 动态链接库查找方法;查找动态链接库位置; LIBRARY_PATH 和 LD_LIBRARY_PATH 的区别;LD_LIBRARY_PATH and LD_RUN_PATH的区别;
今天配置之前项目的时候,发现有些动态链接库变了,想看看现在应用在使用哪些动态链接库的时候,进一步查了点资料: 下面针对linux动态链接库查找方法和动态链接库位置配置的过程进行记录: LIBRARY_ ...
- Linux 动态链接库
如何使用动态链接库 Linux下打开使用动态链接库需要三步(实际上和windows下基本一样):1.加载动态链接库,通过调用库函数dlopen()获得链接库的句柄,对应于windows下的 AfxLo ...
- Linux 动态链接库学习笔记
参考资料: http://www.linuxidc.com/Linux/2012-01/50739.htm http://www.yolinux.com/TUTORIALS/LibraryArchiv ...
- linux动态链接库---一篇讲尽
一般我们在Linux下执行某些外部程序的时候可能会提示找不到共享库的错误, 比如: tmux: error while loading shared libraries: libevent-1.4.s ...
- Linux动态链接库的生成和使用
目录 1. 编写C程序 2. 编译动态链接库 3. 使用共享库 4. 执行程序 5. 参考资料 1. 编写C程序 比如编写myfunc.c文件,里面包含两个函数,一个是say_hello,另一个是ca ...
- Linux 动态链接库 - dll劫持
如何使用动态链接库 Linux下打开使用动态链接库需要三步(实际上和windows下基本一样):1.加载动态链接库,通过调用库函数dlopen()获得链接库的句柄,对应于windows下的 AfxLo ...
- Linux动态链接库的使用
1.前言 在实际开发过程中,各个模块之间会涉及到一些通用的功能,比如读写文件,查找.排序.为了减少代码的冗余,提高代码的质量,可以将这些通用的部分提取出来,做出公共的模块库.通过动态链接库可以实现多个 ...
- linux动态链接库
前言 静态链接库会编译进可执行文件,并被加载到内存,会造成空间浪费 静态链接库对程序的更新.部署.发布带来麻烦.如果静态库更新了,使用它的应用程序都需要重新编译.发布给用户(对于玩家来说,可能是一个很 ...
随机推荐
- asp.net core 中的SignalR与web前端进行实时通信
一.介绍 SignalR是.net 开源库,用于构建需要实时进行用户交互和数据更新的web应用,如在线聊天,游戏,天气等实时应用程序,且简化了构建实时应用的过程,包括服务端库和js端库,继承了数种常见 ...
- 用户组修改工具samusrgrp
用户组修改工具samusrgrp Windows系统内置了很多用户组,如Administrators.PowerUser.User等.用户隶属不同的组,就具备对应的权限.Kali Linux提供一 ...
- 為你的文件夾添加“使用CMD命令打開”菜單
最近在項目中,經常使用要使用一些python命令,要打開cmd窗口,再pushd或cd切換到某個文件夾,相當麻煩.於是想,何不在“文件夾”中添加右鍵“pushd”命令呢? 有了目的性,一切似乎就變得簡 ...
- android studio 使用总结
网站1:http://stormzhang.com/posts.html 网站2:http://blog.csdn.net/hyr83960944/article/details/38388429
- Linux学习笔记08—如何关闭防火墙
Linux系统下面自带了防火墙iptables,iptables可以设置很多安全规则.但是如果配置错误很容易导致各种网络问题,那么如果要关闭禁用防火墙怎么操作呢,咗嚛本经验以centos系统为例演示如 ...
- spring-boot 速成(3) actuator
actuator 通过暴露一系列的endpoints可以让开发者快速了解spring boot的各项运行指标,比如:线程数,jvm剩余内存等一系列参数. 启用方法很简单,参考下面: dependenc ...
- Google Reader明日关闭:14款替代品对比
北京时间6月30日上午消息,谷歌将于7月1日关闭RSS阅读器服务Google Reader,目前许多用户已转向其他的RSS阅读器服务. 美国科技博客Marketing Land本周对市面上多个RSS阅 ...
- JAVA泛型中的有界类型(extends super)(转)
JDK1.5中引入了泛型(Generic)机制.泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数.这种参数类型可以用在类.接口和方法的创建中,分别称为泛型类.泛型接口.泛型方法. Ja ...
- mysqlsandbox
http://mysqlsandbox.net/ http://www.cnblogs.com/xuanzhi201111/p/3998604.html
- Activity的启动模式详解
Activity的启动模式详解 Activity有四种载入模式:standard(默认), singleTop, singleTask和 singleInstance. (1).standard(默认 ...