在dlopen()函数以指定模式打开指定的动态链接库文件。并返回一个句柄给 dlsym()的调用进程。

使用 dlclose()来卸载打开的库。

功能:打开一个动态链接库,并返回动态链接库的句柄
包括头文件:
#include <dlfcn.h>
函数定义:
void * dlopen( const char * pathname, int mode);
函数描写叙述:
mode是打开方式,其值有多个,不同操作系统上实现的功能有所不同,在linux下,按功能可分为三类:
1、解析方式
RTLD_LAZY:在dlopen返回前,对于动态库中的没有定义的符号不运行解析(仅仅对函数引用有效。对于变量引用总是马上解析)。 RTLD_NOW: 须要在dlopen返回前。解析出全部没有定义符号,假设解析不出来。在dlopen会返回NULL,错误为:: undefined symbol: xxxx.......
2、作用范围,可与解析方式通过“|”组合使用。 RTLD_GLOBAL:动态库中定义的符号可被其后打开的其他库解析。
RTLD_LOCAL: 与RTLD_GLOBAL作用相反,动态库中定义的符号不能被其后打开的其他库重定位。 假设没有指明是RTLD_GLOBAL还是RTLD_LOCAL。则缺省为RTLD_LOCAL。
3、作用方式
RTLD_NODELETE: 在dlclose()期间不卸载库,而且在以后使用dlopen()又一次载入库时不初始化库中的静态变量。这个flag不是POSIX-2001标准。
RTLD_NOLOAD: 不载入库。 可用于測试库是否已载入(dlopen()返回NULL说明未载入,否则说明已载入),也可用于改变已载入库的flag,如:先前载入库的flag为RTLD_LOCAL,用dlopen(RTLD_NOLOAD|RTLD_GLOBAL)后flag将变成RTLD_GLOBAL。这个flag不是POSIX-2001标准。
RTLD_DEEPBIND:在搜索全局符号前先搜索库内的符号。避免同名符号的冲突。这个flag不是POSIX-2001标准。
返回值:
打开错误返回NULL
成功,返回库引用
编译时候要增加 -ldl (指定dl库)
比如
gcc test.c -o test -ldl
#include <stdlib.h>
#include <dlfcn.h>
#include <stdio.h> //申明结构体
typedef struct __test {
int i;
void (* echo_fun)(struct __test *p);
}Test; //供动态库使用的注冊函数
void __register(Test *p) {
p->i = 1;
p->echo_fun(p);
} int main(void) { void *handle = NULL;
char *myso = "./mylib.so"; if((handle = dlopen(myso, RTLD_NOW)) == NULL) {
printf("dlopen - %sn", dlerror());
exit(-1);
} return 0;
}
#include <stdio.h>
#include <stdlib.h> //申明结构体类型
typedef struct __test {
int i;
void (*echo_fun)(struct __test *p);
}Test; //申明注冊函数原型
void __register(Test *p); static void __printf(Test *p) {
printf("i = %dn", p->i);
} //动态库申请一个全局变量空间
//这样的 ".成员"的赋值方式为c99标准
static Test config = {
.i = 0,
.echo_fun = __printf,
}; //载入动态库的自己主动初始化函数
void _init(void) {
printf("initn");
//调用主程序的注冊函数
__register(&config);
}

主程序编译: gcc test.c -ldl -rdynamic

动态库编译: gcc -shared -fPIC -nostartfiles -o mylib.so mylib.c

主程序通过dlopen()载入一个.so的动态库文件, 然后动态库会自己主动执行 _init() 初始化函数, 初始化函数打印一个提示信息, 然后调用主程序的注冊函数给结构体又一次赋值, 然后调用结构体的函数指针, 打印该结构体的值. 这样就充分的达到了主程序和动态库的函数相互调用和指针的相互传递.

gcc參数 -rdynamic 用来通知链接器将全部符号加入到动态符号表中(目的是可以通过使用 dlopen
来实现向后跟踪).

gcc參数 -fPIC 作用: 当使用.so等类的库时,当遇到多个可运行文件共用这一个库时, 在内存中,这个库就不会被复制多份,让每一个可运行文件一对一的使用,而是让多个可运行文件指向一个库文件,达到共用. 宗旨:节省了内存空间,提高了空间利用率.

<pre name="code" class="cpp">dlsym函数:
函数原型是
void* dlsym(void* handle,const char* symbol)
该函数在<dlfcn.h>文件里。 handle是由dlopen打开动态链接库后返回的指针。symbol就是要求获取的函数的名称,函数 返回值是void*,指向函数的地址,供调用使用。

导入库函数使用方法:
 

#include <dlfcn.h>

void* handle = dlopen("./hello.so", RTLD_LAZY);

typedef void (*hello_t)();

hello_t hello = (hello_t) dlsym(handle, "hello");



hello();

dlclose(handle);

注意库函数在库中的定义要用extern“c”来申明,这样在主函数中才干通过“hello”来查找函数。申明的方式有下面两种:

extern "C" int foo;

extern "C" void bar();

            

and 



extern "C" {

     extern int foo;

     extern void bar();

}

导入类库方法:

#include "polygon.hpp" //类定义处



#include <dlfcn.h>



void* triangle = dlopen("./triangle.so", RTLD_LAZY);

create_t* create_triangle = (create_t*) dlsym(triangle, "create");



destroy_t* destroy_triangle = (destroy_t*) dlsym(triangle, "destroy");

polygon* poly = create_triangle();

// use the class



    poly->set_side_length(7);

    cout << "The area is: " << poly->area() << '\n';

// destroy the class



    destroy_triangle(poly);



    // unload the triangle library



    dlclose(triangle);



dlopen 方式调用 Linux 的动态链接库的更多相关文章

  1. .netcore在linux下使用P/invoke方式调用linux动态库

    http://www.mamicode.com/info-detail-2358309.html   .netcore下已经实现了通过p/invoke方式调用linux的动态链接库(*.so)文件 1 ...

  2. linux中动态链接库的创建与使用

    LINUX系统中动态链接库的创建与使用 http://www.cnblogs.com/ardar/articles/357321.html 正常C源文件编写,编译时-shared即可得到SO, gcc ...

  3. Linux 关于动态链接库以及静态链接库的一些概念

    库有动态与静态两种,动态通常用.so为后缀,静态用.a为后缀.例如:libhello.so libhello.a 为了在同一系统中使用不同版本的库,可以在库文件名后加上版本号为后缀,例如: libhe ...

  4. linux下动态链接库解决方案(二)

    以前写过一个关于linux下用c++写动态链接库无法通过的解决方案,今天看到<linux C程序设计-王者归来>这本书,书中有个更容易的解决方案,特此记录下来 书中使用的是c语言,我改用c ...

  5. Python调用C/C++动态链接库

    Python调用C/C++动态链接库 2013年07月26日 ⁄ 综合 ⁄ 共 3219字 ⁄ 字号 小 中 大 ⁄ 评论关闭   吐槽(可略过):不知不觉,4月份毕业,5月份进入团队,已有7个月.大 ...

  6. 【转】Python调用C语言动态链接库

    转自:https://www.cnblogs.com/fariver/p/6573112.html 动态链接库在Windows中为.dll文件,在linux中为.so文件.以linux平台为例说明py ...

  7. 如何在java程序中调用linux命令或者shell脚本

    转自:http://blog.sina.com.cn/s/blog_6433391301019bpn.html 在java程序中如何调用linux的命令?如何调用shell脚本呢? 这里不得不提到ja ...

  8. Python调用C/C++动态链接库的方法详解

    Python调用C/C++动态链接库的方法详解 投稿:shichen2014 这篇文章主要介绍了Python调用C/C++动态链接库的方法,需要的朋友可以参考下 本文以实例讲解了Python调用C/C ...

  9. 文本分类学习 (十)构造机器学习Libsvm 的C# wrapper(调用c/c++动态链接库)

    前言: 对于SVM的了解,看前辈写的博客加上读论文对于SVM的皮毛知识总算有点了解,比如线性分类器,和求凸二次规划中用到的高等数学知识.然而SVM最核心的地方应该在于核函数和求关于α函数的极值的方法: ...

随机推荐

  1. CF402E Strictly Positive Matrix(矩阵,强联通分量)

    题意 给定一个 n∗n 的矩阵 A,每个元素都非负判断是否存在一个整数 k 使得 A^k 的所有元素 >0 n≤2000(矩阵中[i][i]保证为1) 题解 考虑矩阵$A*A$的意义 ,设得到的 ...

  2. Python学习七步走

    在周五的下午三点钟(为什么是这个时间?因为事情总会在周五下午三点钟发生),你收到一条通知,客户发现你的软件出现一个错误.在有了初步的怀疑后,你联系运维,查看你的软件日志以了解发生了什么,因为你记得收到 ...

  3. Android调用camera错误setParameters failed深层解析

    1. Camera Camera是Android framework里面支持的,同意你拍照和拍摄视频的设备,那么,在使用camera开发中总是会遇到一些问题,比例如以下面这样子的: E/Android ...

  4. Objective-C学习笔记(十)——循环语句for和do-while的使用

    在OC中.除了while这样的循环方式外,还有另外for循环和do-while循环.它们在不同的业务逻辑下会有不同的作用.能够和C语言和Java对照着学习. (一)代码一: int main(int ...

  5. java设计模式学习 ----- 单例模式(Singleton)

    单例模式(Singleton) 单例对象(Singleton)是一种经常使用的设计模式. 在Java应用中,单例对象能保证在一个JVM中,该对象仅仅有一个实例存在.单例模式也分三种:懒汉式单例.饿汉式 ...

  6. Linux下清除系统日志方法

    摘要:相信大家都是用过Windows的人.对于Windows下饱受诟病的各种垃圾文件都需要自己想办法删除,不然你的系统将会变得越来越大,越来越迟钝!windows怎么清理垃圾相信大家都知道的,那么li ...

  7. BZOJ 1146 二分+链剖+线段树+treap

    思路: 恶心的数据结构题-- 首先 我们 链剖 把树 变成序列 再 套一个 区间 第K大就好了-- 复杂度(n*log^4n) //By SiriusRen #include <cstdio&g ...

  8. Java:网络传输

    网络以字节码传输 String s = "我恨你"; //转成字节: byte[] brr = s.getBytes();//gbk //iE:utf-8 String s1 = ...

  9. Ubuntu Bonding(16.04网卡绑定)

    UbuntuBonding(网卡绑定) 绑定,也称为端口聚合或链路聚合,意味着将多个网络接口(NIC)组合到单个链路,从而提供高可用性,负载平衡,最大吞吐量或这些组合.注意bonding只能提供链路监 ...

  10. DedeCMS列表页隔行/多行随意换色

    在很多列表调用的时候都需要有隔行换色或者多行不同颜色,特别在全通式的首页轮展图的时候,要想实现轮展图背景随着图片的更换,超过三张或多张的时候,隔行换色已经不能解决问题了,在原来的隔行换色的基础上,进行 ...