动态库的显式调用
显式调用的含义是代码出现库文件名,用户需要自己去
打开和管理库文件。其要点为:
⑴把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./
就行了。
分享到:
相关推荐
opengl的东西)供opengl渲染显示的小程序,其中bmp的是通过分析bmp文件格式读取位图数据和sdl_image两种方式加载,Png和Jpg文件格式比较复杂,所以直接使用libpng和libjpeg库加载。 程序实现了glsl的简单使用,从加载...
Hotpatch 是一个允许正在运行的进程动态加载一个 so 库的 C 库,类似于 Win32 上的 CreateRemoteThread() API。 ... 对于一个正在运行进程仅能动态加载一次 so 库文件。 标签:Hotpatch
文中是linux下 C++动态库 实现接口提供类导出的一个例子 注意其中使用函数返回基类指针的用法,因为Linux的动态链接库不能像MFC中那样直接导出类 一、介绍 如何使用dlopen API动态地加载C++函数和类,是Unix C++...
库的存在极大的提高了C/C++程序的复用性,但是库对于初学者来说有些难以驾驭,本文从Linux的角度浅谈Linux下的静态库、动态库和动态加载库。 Linux库类型 Linux下可以创建两种类型的库: 1、静态库(.a): 在...
新建工程 test_so 在工程->右键->Addlibray->external library->next->选择.so目录 platform下选择linux 就行,其他不选 next->完成 在 Test_SO.cpp 文件中添加 make_so.h 在调用外部函数到地方使用如下 Make_...
在Windows操作系统下,本机库文件的扩展名通常是`.dll`(动态链接库),而在Linux操作系统下,本机库文件的扩展名通常是`.so`(共享对象)。这是由于不同操作系统使用不同的二进制格式和加载机制。 原因如下: 1. ...
Linux-生成动态库工程和操作文件说明、调用加载动态库工程 本机是x86_64的 若想ARM,需加载ARM交叉编译工具链,运行即可 动态库代码在代码下一张
opencv-4.5.5版本编译后的成品,包含java所依赖的jar包以及linux平台下的so文件
Linux操作系统是现在流行的一种免费的...在研究了Linux文件系统及网络传输的原理基础上系统主要实现了对文件的管理,包括创建、删除、重命名、复制、移动和文件权限的修改的功能,以及对字符的搜索和对文件的网络传输。
lua动态链接库的编译 c++调用lua的的方法 linux中调用lua的环境配置
UNIX/LINUX 平台可执行文件加载过程 本文讨论了 UNIX/LINUX 平台下三种主要的可执行文件格式: a.out(assembler and link editor output 汇编器和链接编辑器的输出)、 COFF(Common Object File Format 通用...
QT在Ubuntu系统的开发,由于Linux系统不支持dll文件,而是支持so文件,因此,需要生成so文件从而能够被qt在Linux系统的调用,还望各位博友多多支持
一、历史问题关于动态链接,可以说由来已久 二、代码举例讲了这么多,还没有真正讲到在intel 32平台下linux动态链接库的加载与调用 三、_dl_open加
hdf5 在linux下的安装包 如果想在linux下解析hdf5文件 需要 加载该库文件 并编译生成。a文件
本代码将将win、linux加载、卸载动态库,并从动态库链接模块中获取类实例或函数地址等封装成统一的API接口,并集成在dllLoad.h/dllLoad.cpp中实现。构建一个注册类RegisterM,内置一个map容器,用来装载加载的动态...
libopenh264库文件,适用于linux64。
Linux下不能加载动态库问题 当出现下边异常情况 ./test: error while loading shared libraries: libmfs_open.so: cannot open shared object file: No such file or directory 若动态库的路径在(/usr/cluster/....
一、历史问题关于动态链接,可以说由来已久 二、代码举例讲了这么多,还没有真正讲到在intel 32平台下linux动态链接库的加载与调用 三、_dl_open加
通过shared和fPIC编译参数生产so动态链接库文件。程序在调用库函数时,只需要连接上这个库即可。例如下面实现一个简单的整数四则运输的动态链接库,定义的caculate.h和caculate.c两个文件,生产libcac.so动态链接库...
springboot+jna/jni调用动态so/dll库