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动态链接库
前言 静态链接库会编译进可执行文件,并被加载到内存,会造成空间浪费 静态链接库对程序的更新.部署.发布带来麻烦.如果静态库更新了,使用它的应用程序都需要重新编译.发布给用户(对于玩家来说,可能是一个很 ...
随机推荐
- Android Data Binding
Android官方数据绑定框架DataBinding, 1.什么是DataBinding 2.DataBinding基础用法 3.DataBinding原理 4.表达式 5.null检查 6.incl ...
- poj 2253 最短路floyd **
题意:有两只青蛙和若干块石头,现在已知这些东西的坐标,两只青蛙A坐标和青蛙B坐标是第一个和第二个坐标,现在A青蛙想要到B青蛙那里去,并且A青蛙可以借助任意石头的跳跃,而从A到B有若干通路,问从A到B的 ...
- js跨域请求(jsonp)
jsonp是跨域请求的手段之一. jsonp的原理: 先来看看下面这段代码 <!DOCTYPE html> <html lang="en"> <hea ...
- Slickflow.NET 开源工作流引擎高级开发(一) -- 流程外部事件的调用和变量存储实现
前言:流程实现基本流转功能外,通常也需要调用外部事件,用于和业务系统的交互,同时存储一些流程变量,用于追踪和记录业务数据变化对流程流转的影响. 1. 流程事件 流程执行过程中,伴随各种事件的发生,而且 ...
- shell脚本调用C语言之字符串切分函数——strtok
今天上午在写一个需求,要求的比较急,要求当天完成,我大致分析了一下,可以采用从shell脚本中插入一连串的日期,通过调用proc生成的可执行文件,将日期传入后台数据库,在数据库中进行计算.需要切分日期 ...
- Emmet 语法介绍
一.生成 HTML 文档初始结构 HTML 文档的初始结构,就是包括 doctype.html.head.body 以及 meta 等内容.你只需要输入一个 “!” 就可以生成一个 HTML5 的标准 ...
- 新手学cocos2dx,centos7下的安装过程
背景 打算学写游戏,新手向,当然从cocos2d-x开始. 看了cocos的文档,安装是针对ubuntu的,这里记录下centos7上安装.编译.运行测试的过程. 如果你已经有ubuntu,不推荐看此 ...
- chrome ui源码剖析-ViewProp
先熟悉set的find原理 http://www.cnblogs.com/Clingingboy/p/3252136.html 这个类改造下,还是非常实用的,可以对于不同的类型做数据存储 一.Vi ...
- [Node.js]操作mysql
摘要 上篇文章介绍了node.js操作redis的简单实例,这里介绍如何操作mysql. 安装 安装mysql模块 cnpm install mysql 一个例子 新建一个mysql.js的文件,代码 ...
- 哈希小demo hashCode取模
package demo; import java.util.ArrayList; import java.util.List; class Person { private String usern ...