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)的使用的更多相关文章

  1. Linux动态链接库的创建与使用

    Linux动态链接库的创建与使用1. 介绍     使用GNU的工具我们如何在Linux下创建自己的程序函数库?一个“程序函数库”简单的说就是一个文件包含了一些编译好的代码和数据,这些编译好的代码和数 ...

  2. linux 动态链接库查找方法;查找动态链接库位置; LIBRARY_PATH 和 LD_LIBRARY_PATH 的区别;LD_LIBRARY_PATH and LD_RUN_PATH的区别;

    今天配置之前项目的时候,发现有些动态链接库变了,想看看现在应用在使用哪些动态链接库的时候,进一步查了点资料: 下面针对linux动态链接库查找方法和动态链接库位置配置的过程进行记录: LIBRARY_ ...

  3. Linux 动态链接库

    如何使用动态链接库 Linux下打开使用动态链接库需要三步(实际上和windows下基本一样):1.加载动态链接库,通过调用库函数dlopen()获得链接库的句柄,对应于windows下的 AfxLo ...

  4. Linux 动态链接库学习笔记

    参考资料: http://www.linuxidc.com/Linux/2012-01/50739.htm http://www.yolinux.com/TUTORIALS/LibraryArchiv ...

  5. linux动态链接库---一篇讲尽

    一般我们在Linux下执行某些外部程序的时候可能会提示找不到共享库的错误, 比如: tmux: error while loading shared libraries: libevent-1.4.s ...

  6. Linux动态链接库的生成和使用

    目录 1. 编写C程序 2. 编译动态链接库 3. 使用共享库 4. 执行程序 5. 参考资料 1. 编写C程序 比如编写myfunc.c文件,里面包含两个函数,一个是say_hello,另一个是ca ...

  7. Linux 动态链接库 - dll劫持

    如何使用动态链接库 Linux下打开使用动态链接库需要三步(实际上和windows下基本一样):1.加载动态链接库,通过调用库函数dlopen()获得链接库的句柄,对应于windows下的 AfxLo ...

  8. Linux动态链接库的使用

    1.前言 在实际开发过程中,各个模块之间会涉及到一些通用的功能,比如读写文件,查找.排序.为了减少代码的冗余,提高代码的质量,可以将这些通用的部分提取出来,做出公共的模块库.通过动态链接库可以实现多个 ...

  9. linux动态链接库

    前言 静态链接库会编译进可执行文件,并被加载到内存,会造成空间浪费 静态链接库对程序的更新.部署.发布带来麻烦.如果静态库更新了,使用它的应用程序都需要重新编译.发布给用户(对于玩家来说,可能是一个很 ...

随机推荐

  1. 简单的CSS3 Loading动画

    最终效果如图一,gif图片稍微有点卡顿,事实上代码在浏览器里执行得很流畅.这里面用到的css3技术非常简单,分别是border-radius.伪元素.css3关键帧以及animation动画. 首先整 ...

  2. python异常装饰器--比较全的版本了

    # 异常捕获装饰器(亦可用于类方法) def try_except_log(f=None, max_retries: int = 5, delay: (int, float) = 1, step: ( ...

  3. java过滤器、监听器、拦截器机制

    一.过滤器 Filter也称之为过滤器,它是Servlet技术中最实用的技术,Web开发人员通过Filter技术,对web服务器管理的所有web资源:例如Jsp, Servlet, 静态图片文件或静态 ...

  4. 慎重使用volatile关键字

    volatile关键字相信了解Java多线程的读者都很清楚它的作用.volatile关键字用于声明简单类型变量,如int.float.boolean等数据类型.如果这些简单数据类型声明为volatil ...

  5. 分类器评估方法:ROC曲线

    注:本文是人工智能研究网的学习笔记 ROC是什么 二元分类器(binary classifier)的分类结果 ROC空间 最好的预测模型在左上角,代表100%的灵敏度和0%的虚警率,被称为完美分类器. ...

  6. hadoop 基础视频1

    hadoop 基础视频1 一, 大致内容: 1, 源起与体系结构2,实施Hadoop 集群3,分布式HDFS, 大数据存储实战4,Map-Reduce 体系架构5,Map-Reduce 数据分析之一 ...

  7. FireDAC 下的 Sqlite [7] - 备份、优化、事务(Transaction)

    用 TFDSQLiteBackup 控件, 两三行代码即可完成 Sqlite 数据库的备份. procedure TForm1.Button1Click(Sender: TObject); begin ...

  8. Java+Windows+ffmpeg实现视频转换

    最近由于项目需要,研究了一下如何用Java实现视频转换,“着实”废了点心思,整理整理,写出给自己备忘下. 思路 由于之前没有没法过相关功能的经验,一开始来真不知道从哪里入手.当然,这个解决,googl ...

  9. 【转】JavaScript eval处理JSON数据 为什么要加括号

    由于Ajax的兴起,JSON这种轻量级的数据格式作为客户端与服务器之间的传输格式逐渐地流行起来,进而出现的问题是如何将服务器端构建好的JSON数据转化为可用的JavaScript对象.利用eval函数 ...

  10. 打印 Go 结构体(struct)信息:fmt.Printf("%+v", user)

    package main import "fmt" // 用户 type User struct { Id int Name string Age int } func main( ...