`
yidongkaifa
  • 浏览: 4071579 次
文章分类
社区版块
存档分类
最新评论

Linux下动态加载SO文件

 
阅读更多

动态库的显式调用

显式调用的含义是代码出现库文件名,用户需要自己去

打开和管理库文件。其要点为:

⑴把dlfcn.h系统头文件包含进来

⑵用dlopen函数打开库文件,并指定打开方式

dllope的的第一个参数为共享库的名称,将会在下面位置查找指定的共享库。

①环境变量LD_LIBRARY_PATH列出的用分号间隔的所有目录。

②文件/etc/ld.so.cache中找到的库的列表,由ldconfig命令刷新。

③目录usr/lib。

④目录/lib。

⑤当前目录。

第二个参数为打开共享库的方式。有两个取值

①RTLD_NOW:将共享库中的所有函数加载到内存

②RTLD_LAZY:会推后共享库中的函数的加载操作,直到调用dlsym()时方加载某函数

⑶用dlerror()函数测试是否打开成功,并进行错误处理;

⑷用dlsym获得函数地址,存放在一个函数指针中

⑸用获得的函数指针进行函数调用。

⑹程序结束时用dlclose关闭打开的动态库,防止资源泄露。

⑺用ldconfig工具把动态库的路径加到系统库列表中

1、编写测试文件

//main.c 测试动态库显式调用的程序

#include<dlfcn.h>//用于动态库管理的系统头文件

#include"myalib.h" //要把函数的头文件包含进来,否则编译时会报错

int main(intargc,char* argv[])

{

//声明对应的函数的函数指针

void(*pTest)();

//加载动态库

void*pdlHandle = dlopen("libtest.so", RTLD_LAZY);

//错误处理

if(pdlHandle == NULL ) {

printf("Failed load library\n");

return -1;

}

char* pszErr = dlerror();

if(pszErr != NULL)

{

printf("%s\n", pszErr);

return -1;

}

//获取函数的地址

pTest = dlsym(pdlHandle, "test");

pszErr = dlerror();

if(pszErr != NULL)

{

printf("%s\n", pszErr);

dlclose(pdlHandle);

return -1;

}

//实现函数调用

(*pTest)();

//程序结束时关闭动态库

dlclose(pdlHandle);

return0;

}

2、编译测试文件使用-ldl选项指明生成的对象模块需要使用共享库

gcc -o main -ldlmain.c

执行完后就生成了一个main文件

3、执行测试程序

执行 ./main

输出

test

说明成功。

----------------------------------分割------------------------------------------

//say.c

#include <stdio.h>

int say(char **str){
printf("%s\n",str);

}

将say.c 生成共享库的编译:
gcc -o dlopen.so -shared say.c

//使用dlopen函数动态加载库的源代码


#include <stdio.h>
#include <dlfcn.h>
#include <unistd.h>

void show_help(char *msg){
if(msg == NULL){
printf("Usage:mydlopen dlopen.so say stringtosay\n");
}else{
printf("%s\n",msg);
}
exit(1);
}
int main(int ac,char ** av){

if(ac < 3){
show_help(NULL);
}
void *handle;
//void *pfunc;

int (*pfunc)(char *str);
char * filename = av[1];
char * func = av[2];
char * word = av[3];
char * error;
handle = dlopen(filename,RTLD_LAZY);
if(!handle){
printf("Error: handle\n");
return 1;
}

pfunc = (int (*)(char *))dlsym(handle,func);
if((error=dlerror()) != NULL){
printf("Error: dlsym\n");
return 2;
}
(*pfunc)(word);

dlclose(handle);
return 0;

}

//编译命令:

gcc -o mydlopen mydlopen.c-ldl

注意事项:

1.dlsym返回的指针是无类型的,要转换的指定的函数的类型。
2.使用函数指针时的写法: (*pfunc)(word); 不能直接写成pfunc(word);会段错误的
3.C还不支持默认参数,写show_help时不能给msg以NULL的默认值
3.编译时要使用共享库dl 其中有dlopen dlsynmdlerror dlclose 函数

使用命令:

./mydlopen ./dlopen.so say aaaabbbdddd

------------------------------------分割------------------------------------------

说明:pfunc = (int(*)(char *))dlsym(handle,func);

其中char *是将参数强转,因为int (*pfunc)(char*str);是这样定义的。

如果int (*pfunc)(char *str,int number);这样定义,那么强转的时候应该这样写:

pfunc = (int(*)(char *,int))dlsym(handle,func);

--------------------------------------分割-----------------------------------------

编译的时候的说明,比如现在的文件目录树如下:

1.work/

2.|--head.h

3.|--main.c

4.|--func.c

5.|--func2.c

这个时候欲将func2.c编译成动态链接库dlfunc.so,而func2.c中的函数用到了head.h和func.c里面的变量和函数,这个时候应该使用命令:

gcc -o dlfunc.so-shared func2.c func.c -I./

这样就生成了dlfunc.so。

然后编译连接主程序。

gcc -o test main.c-ldl -I./

就行了。

分享到:
评论

相关推荐

    linux下opengl加载bmp、png、jpg格式图片

    opengl的东西)供opengl渲染显示的小程序,其中bmp的是通过分析bmp文件格式读取位图数据和sdl_image两种方式加载,Png和Jpg文件格式比较复杂,所以直接使用libpng和libjpeg库加载。 程序实现了glsl的简单使用,从加载...

    so动态加载库Hotpatch.zip

    Hotpatch 是一个允许正在运行的进程动态加载一个 so 库的 C 库,类似于 Win32 上的 CreateRemoteThread() API。 ... 对于一个正在运行进程仅能动态加载一次 so 库文件。 标签:Hotpatch

    linux下C++动态链接C++库示例

    文中是linux下 C++动态库 实现接口提供类导出的一个例子 注意其中使用函数返回基类指针的用法,因为Linux的动态链接库不能像MFC中那样直接导出类 一、介绍 如何使用dlopen API动态地加载C++函数和类,是Unix C++...

    Linux下的静态库、动态库和动态加载库

    库的存在极大的提高了C/C++程序的复用性,但是库对于初学者来说有些难以驾驭,本文从Linux的角度浅谈Linux下的静态库、动态库和动态加载库。  Linux库类型  Linux下可以创建两种类型的库:  1、静态库(.a): 在...

    Linux下 Qt创建.so与调用

    新建工程 test_so 在工程-&gt;右键-&gt;Addlibray-&gt;external library-&gt;next-&gt;选择.so目录 platform下选择linux 就行,其他不选 next-&gt;完成 在 Test_SO.cpp 文件中添加 make_so.h 在调用外部函数到地方使用如下 Make_...

    Java-Linux环境下OpenCV本机库文件

    在Windows操作系统下,本机库文件的扩展名通常是`.dll`(动态链接库),而在Linux操作系统下,本机库文件的扩展名通常是`.so`(共享对象)。这是由于不同操作系统使用不同的二进制格式和加载机制。 原因如下: 1. ...

    Linux-生成动态库工程和操作文件说明、调用加载动态库工程

    Linux-生成动态库工程和操作文件说明、调用加载动态库工程 本机是x86_64的 若想ARM,需加载ARM交叉编译工具链,运行即可 动态库代码在代码下一张

    opencv-4.5.5编译后的jar包和linux平台的so文件

    opencv-4.5.5版本编译后的成品,包含java所依赖的jar包以及linux平台下的so文件

    linux下文件管理系统的研究与实现

    Linux操作系统是现在流行的一种免费的...在研究了Linux文件系统及网络传输的原理基础上系统主要实现了对文件的管理,包括创建、删除、重命名、复制、移动和文件权限的修改的功能,以及对字符的搜索和对文件的网络传输。

    linux环境中c++调用lua动态链接库以及编译方法

    lua动态链接库的编译 c++调用lua的的方法 linux中调用lua的环境配置

    UNIX/LINUX 平台可执行文件加载过程

    UNIX/LINUX 平台可执行文件加载过程 本文讨论了 UNIX/LINUX 平台下三种主要的可执行文件格式: a.out(assembler and link editor output 汇编器和链接编辑器的输出)、 COFF(Common Object File Format 通用...

    qt生成so文件,再调用so文件-1.pdf

    QT在Ubuntu系统的开发,由于Linux系统不支持dll文件,而是支持so文件,因此,需要生成so文件从而能够被qt在Linux系统的调用,还望各位博友多多支持

    Intel平台下Linux中ELF文件动态链接的加载1

    一、历史问题关于动态链接,可以说由来已久 二、代码举例讲了这么多,还没有真正讲到在intel 32平台下linux动态链接库的加载与调用 三、_dl_open加

    hdf5 Linux下的安装包 以及make文件

    hdf5 在linux下的安装包 如果想在linux下解析hdf5文件 需要 加载该库文件 并编译生成。a文件

    c/c++中如何实现动态库动态加载的完整工程示例代码

    本代码将将win、linux加载、卸载动态库,并从动态库链接模块中获取类实例或函数地址等封装成统一的API接口,并集成在dllLoad.h/dllLoad.cpp中实现。构建一个注册类RegisterM,内置一个map容器,用来装载加载的动态...

    libopenh264-1.8.0-linux64.4.so.bz2

    libopenh264库文件,适用于linux64。

    Linux程序运行时加载动态库失败的解决方法

    Linux下不能加载动态库问题 当出现下边异常情况 ./test: error while loading shared libraries: libmfs_open.so: cannot open shared object file: No such file or directory 若动态库的路径在(/usr/cluster/....

    Intel平台下Linux中ELF文件动态链接的加载、解析及实例分析(一)-加载1

    一、历史问题关于动态链接,可以说由来已久 二、代码举例讲了这么多,还没有真正讲到在intel 32平台下linux动态链接库的加载与调用 三、_dl_open加

    Linux动态链接库的使用

    通过shared和fPIC编译参数生产so动态链接库文件。程序在调用库函数时,只需要连接上这个库即可。例如下面实现一个简单的整数四则运输的动态链接库,定义的caculate.h和caculate.c两个文件,生产libcac.so动态链接库...

    springboot+jna/jni调用动态so/dll库

    springboot+jna/jni调用动态so/dll库

Global site tag (gtag.js) - Google Analytics