dlopen

基本定义

  功能:打开一个动态链接库 
  包含头文件: 
  #include <dlfcn.h> 
  函数定义: 
  void * dlopen( const char * pathname, int mode ); 
  函数描述: 
  在dlopen的()函数以指定模式打开指定的动态连接库文件,并返回一个句柄给调用进程。使用dlclose()来卸载打开的库。 
  mode:分为这两种 
  RTLD_LAZY 暂缓决定,等有需要时再解出符号 
  RTLD_NOW 立即决定,返回前解除所有未决定的符号。 
  RTLD_LOCAL 
  RTLD_GLOBAL 允许导出符号 
  RTLD_GROUP 
  RTLD_WORLD 
  返回值: 
  打开错误返回NULL 
  成功,返回库引用 
  编译时候要加入 -ldl (指定dl库) 
  例如 
  gcc test.c -o test -ldl
编辑本段
使用 dlopen
  dlopen()是一个强大的库函数。该函数将打开一个新库,并把它装入内存。该函数主要用来加载库中的符号,这些符号在编译的时候是不知道的。比如 Apache Web 服务器利用这个函数在运行过程中加载模块,这为它提供了额外的能力。一个配置文件控制了加载模块的过程。这种机制使得在系统中添加或者删除一个模块时,都不需要重新编译了。 
  可以在自己的程序中使用 dlopen()。dlopen() 在 dlfcn.h 中定义,并在 dl 库中实现。它需要两个参数:一个文件名和一个标志。文件名可以是我们学习过的库中的 soname。标志指明是否立刻计算库的依赖性。如果设置为 RTLD_NOW 的话,则立刻计算;如果设置的是 RTLD_LAZY,则在需要的时候才计算。另外,可以指定 RTLD_GLOBAL,它使得那些在以后才加载的库可以获得其中的符号。

  当库被装入后,可以把 dlopen() 返回的句柄作为给 dlsym() 的第一个参数,以获得符号在库中的地址。使用这个地址,就可以获得库中特定函数的指针,并且调用装载库中的相应函数。

--------------------------------------------------------------------------------------------------------------------------

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

取动态对象地址:
#include <dlfcn.h>
void *dlsym(void *pHandle, char *symbol);
dlsym根据动态链接库操作句柄(pHandle)与符号(symbol),返回符号对应的地址。
使用这个函数不但可以获取函数地址,也可以获取变量地址。比如,假设在so中
定义了一个void mytest()函数,那在使用so时先声明一个函数指针
void (*pMytest)(),然后使用dlsym函数将函数指针pMytest指向mytest函数,
pMytest = (void (*)())dlsym(pHandle, "mytest");

--------------------------------------------------------------------------------------------------------------------------

dlclose
  dlclose() 
  包含头文件: 
  #include <dlfcn.h> 
  函数原型为: 
  int dlclose (void *handle); 
  函数描述: 
   dlclose用于关闭指定句柄的动态链接库,只有当此动态链接库的使用计数为0时,才会真正被系统卸载。

--------------------------------------------------------------------------------------------------------------------------

dlerror
  dlerror() 
  包含头文件: 
  #include <dlfcn.h> 
  函数原型: 
  const char *dlerror(void); 
  函数描述: 
  当动态链接库操作函数执行失败时,dlerror可以返回出错信息,返回值为NULL时表示操作函数执行成功。

LINUX创建与使用动态链接库并不是一件难事。
  编译函数源程序时选用-shared选项即可创建动态链接库,注意应以.so后缀命名,最好放到公用库目录(如/lib,/usr/lib等)下面,并要写好用户接口文件,以便其它用户共享。
  使用动态链接库,源程序中要包含dlfcn.h头文件,写程序时注意dlopen等函数的正确调用,编译时要采用-rdynamic选项与-ldl选项 ,以产生可调用动态链接库的执行代码。

EXAMPLE
Load the math library, and print the cosine of 2.0:
#include <stdio.h>
#include <dlfcn.h> int main(int argc, char **argv) {
void *handle;
double (*cosine)(double);
char *error; handle = dlopen ("libm.so", RTLD_LAZY);
if (!handle) {
fprintf (stderr, "%s\n", dlerror());
exit();
} cosine = dlsym(handle, "cos");
if ((error = dlerror()) != NULL) {
fprintf (stderr, "%s\n", error);
exit();
} printf ("%f\n", (*cosine)(2.0));
dlclose(handle);
return ;
} If this program were in a file named "foo.c", you would build the program with the following command: gcc -rdynamic -o foo foo.c -ldl

LINUX下动态链接库的使用-dlopen dlsym dlclose dlerror(转)的更多相关文章

  1. LINUX下动态链接库的使用-dlopen dlsym dlclose dlerror

    本定义 功能:打开一个动态链接库 包含头文件: #include <dlfcn.h> 函数定义: void * dlopen( const char * pathname, int mod ...

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

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

  3. 加载动态链接库——dlopen dlsym dlclose

    DLOPEN DLMOPEN DLCLOSE NAME     dlclose, dlopen, dlmopen - 打开/关闭共享对象 SYNOPSIS #include <dlfcn.h&g ...

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

    1.c++无法直接调用用c写的动态链接库,如果调用的话可能需要用到一些交叉编译的知识: 2.在c++写的动态链接库无法被调用成功的反思: 在linux下,通常都是使用g++编译器("g++ ...

  5. linux下动态链接库.so文件 静态链接库.a文件创建及使用

    转摘网址为:http://www.cnblogs.com/fengyv/archive/2012/08/10/2631313.html Linux下文件的类型是不依赖于其后缀名的,但一般来讲:    ...

  6. Linux下动态链接库和静态链接库

    第一部分:编译过程 先了解一下linux下C代码的编译过程,C代码的编译,一般分成四个阶段,包括:预编译,编译,汇编和链接,这四个阶段的分工是 预处理过程,负责头文件展开,宏替换,条件编译的选择,删除 ...

  7. linux下动态链接库(.so)的显式调用和隐式调用

    进入主题前,先看看两点预备知识. 一.显式调用和隐式调用的区别 我们知道,动态库相比静态库的区别是:静态库是编译时就加载到可执行文件中的,而动态库是在程序运行时完成加载的,所以使用动态库的程序的体积要 ...

  8. Linux下动态链接库 与gcc 选项

    -L 编译时查找动态链接库的路径 -lxxx(小写)  e.g -lcudart   = link libcudart.so  , -I(大写) 头文件的路径 -rpath (-R), 编译时指定链接 ...

  9. Linux下动态链接库加载路径

    引子 近日,服务器迁移后,偷懒未重新编译nginx的,直接./nginx启动,结果遇到如下问题: "error while loading shared libraries" 这是 ...

随机推荐

  1. 阿里云Linux服务器挂载数据盘

    步骤1.登录服务器2.检查磁盘信息 命令:fdisk -l3.磁盘分区 命令:fdisk /dev/xvdb 查看命令帮助 m n //新增一个分区 p //建立一个主分区 1 //设置盘符为1 回车 ...

  2. AngularJs-$parsers自我理解-解析

    $parsers 首先先了解下它具体的作用,当用户与控制器进行交互的时候.ngModelController中的$setViewValue()方法就会被调用,$parsers的数组中函数就会以流水线的 ...

  3. iOS 根据生日得到生肖,星座,年龄的算法

    根据用户生日,得到相应的年龄,星座和生肖.有的项目中可能会用到,贴出来共享. 得到年龄,这个很简单了: - (void)getAgeWith:(NSDate*)birthday{ //日历 NSCal ...

  4. HDU 3787 A+B 模拟题

    解题报告:就是输入两个用逗号隔开的数字,求出这两个数字的和,并且用正常的方式输出来.直接写一个函数将一个包含逗号的数字转换成十进制的数返回就行了.这里推荐一个函数atoi(),参数是char*型的,然 ...

  5. [译]使用chage来管理Linux密码过期时间的七个例子

    本文译自 7 Examples to Manage Linux Password Expiration and Aging Using chage 本文主要介绍命令chage的使用,译文会对原文内容会 ...

  6. 转载 你不知道的super

    http://funhacks.net/2016/11/09/super/ super仅被用于新式类 在类的继承中,如果重定义某个方法,该方法会覆盖父类的同名方法,但有时,我们希望能同时实现父类的功能 ...

  7. WIN10文件无法自动刷新问题解决方法

    Window10系统有时候会遇到以下类似的问题 1.文件删除后,图标还在,无法自动刷新屏幕,按F5或右键菜单刷新后才消失 2.文件粘贴后,不显示,刷新后才显示 3.回收站清理后,文件图标仍显示有垃圾 ...

  8. Jenkins的安装及使用(一)

    操作环境:Windows7 一.环境准备 1 安装JDK 本文采用jdk-8u111-windows-x64.exe: 安装完成后配置环境变量. 2 配置tomcat 本文采用tomcat8,免安装版 ...

  9. expect学习笔记及实例详解【转】

    1. expect是基于tcl演变而来的,所以很多语法和tcl类似,基本的语法如下所示:1.1 首行加上/usr/bin/expect1.2 spawn: 后面加上需要执行的shell命令,比如说sp ...

  10. SpringBoot修改默认端口号,session超时时间

    有时候我们可能需要启动不止一个SpringBoot,而SpringBoot默认的端口号是8080,所以这时候我们就需要修改SpringBoot的默认端口了.修改SpringBoot的默认端口有两种方式 ...