zl程序教程

您现在的位置是:首页 >  系统

当前栏目

Linux动态链接库的使用

Linux 动态链接库 使用
2023-09-14 08:59:45 时间

1、前言

在实际开发过程中,各个模块之间会涉及到一些通用的功能,比如读写文件,查找、排序。为了减少代码的冗余,提高代码的质量,可以将这些通用的部分提取出来,做出公共的模块库。通过动态链接库可以实现多个模块之间共享公共的函数。之前看《程序员的自我修养》中讲到程序的链接和装入过程,这些玩意都是底层的,对于理解程序的编译过程有好处。http://www.ibm.com/developerworks/cn/linux/l-dynlink/博文介绍了程序的链接和装入过程。本文重点在于应用,如何编写和使用动态链接库,后续使用动态链接库实现一个插件程序。

2、动态链接库生产

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

程序代码如下:

复制代码
/*caculate.h*/

#ifndef CACULATE_HEAD_

#define CACULATE_HEAD_

int add(int a, int b);

int sub(int a, int b);

int div(int a, int b);

int mul(int a, int b);

#endif
复制代码
复制代码

/*caculate.c文件*/
#include "caculate.h" //求两个数的和 int add(int a, int b) return (a + b); int sub(int a, int b) return (a - b); int div(int a, int b) return (int)(a / b); int mul(int a, int b) return (a * b); }
复制代码

编译生产libcac.so文件如下: gcc -shared -fPIC caculate.c -o libcac.so
编写一个测试程序调用此动态链接库的函数,程序如下所示:

复制代码
#include stdio.h 

#include "caculate.h"

int main()

 int a = 20;

 int b = 10;

 printf("%d + %d = %d\n", a, b, add(a, b));

 printf("%d - %d = %d\n", a, b, sub(a, b));

 printf("%d / %d = %d\n", a, b, div(a, b));

 printf("%d * %d = %d\n", a, b, mul(a, b));

 return 0;

}
复制代码

编译生产可执行文件main如下:gcc main.c -o main -L ./ -lcac   (其中-L指明动态链接库的路径,-l后是链接库的名称,省略lib)
程序执行结果如下所示:

 3、获取动态链接库的函数
linux提供dlopen、dlsym、dlerror和dlcolose函数获取动态链接库的函数。通过这个四个函数可以实现一个插件程序,方便程序的扩展和维护。函数格式如下所示:

复制代码
#include dlfcn.h 

void *dlopen(const char *filename, int flag);

char *dlerror(void);

void *dlsym(void *handle, const char *symbol);

int dlclose(void *handle);

 Link with -ldl.
复制代码

dlopen()是一个强大的库函数。该函数将打开一个新库,并把它装入内存。该函数主要用来加载库中的符号,这些符号在编译的时候是不知道的。写个测试程序调用上面生产libcac.so库如下所示:

复制代码
#include stdio.h 

#include dlfcn.h 

#define DLL_FILE_NAME "libcac.so"

int main()

 void *handle;

 int (*func)(int, int);

 char *error;

 int a = 30;

 int b = 5;

 handle = dlopen(DLL_FILE_NAME, RTLD_NOW);

 if (handle == NULL)

 fprintf(stderr, "Failed to open libaray %s error:%s\n", DLL_FILE_NAME, dlerror());

 return -1;

 func = dlsym(handle, "add");

 printf("%d + %d = %d\n", a, b, func(a, b));

 func = dlsym(handle, "sub");

 printf("%d + %d = %d\n", a, b, func(a, b));

 func = dlsym(handle, "div");

 printf("%d + %d = %d\n", a, b, func(a, b));

 func = dlsym(handle, "mul");

 printf("%d + %d = %d\n", a, b, func(a, b));

 dlclose(handle);

 return 0;

}
复制代码

程序执行结果如下所示:gcc call_main.c -o call_main -ldl


Linux 动态链接库(.so)的使用 1. 背景 库:就是已经编写好的,后续可以直接使用的代码。 c++静态库:会合入到最终生成的程序,使得结果文件比较大。优点是不再有任何依赖。 c++动态库:动态库,一个文件可以多个代码同时使用内存中只有一份,节省内存,可以随主代码一起编译。
linux找不到动态链接库 .so文件的解决方法(转自:http://www.cnblogs.com/xudong-bupt/p/3698294.html) linux找不到动态链接库 .so文件的解决方法 如果使用自己手动生成的动态链接库.so文件,但是这个.so文件,没有加入库文件搜索路劲中,程序运行时可能会出现找不到动态链接库的情形。 可以通过ldd命名来查看可执行文件依赖的动态链接库,如下(其中D为可执行程序):  其中的libjson_linux-gcc-4.6_libmt.so cannot found。 解决这个问题:  (1)在
linux下查看动态链接库so文件的依赖的相关组建 我们很多c程序在windows下是以dll形式展现的,在linux则是以so 形式展现的。   windows一般不会因为编译dll文件的编译器版本不同而出先dll文件不能执行。   但是linux下,不同版本内核的linux下编译的c程序,在其他版本的linux下就容易出现无法执行的问题。
linux下查看动态链接库依赖关系的命令 x86: ldd *.so arm: arm-linux-readelf -d *.so 实际例子: 以项目中用到的库librtsp.so分析: lijun@ubuntu:~/workspace$ arm-hisiv100nptl- linux下查看动态链接库依赖关系的命令 x86:ldd    *.so arm:arm-linux-readelf    -d    *.so 实际例子:以项目中用到的库librtsp.so分析:lijun@ubuntu:~/workspace$ arm-hisiv100nptl-linux-ld -d librtsp.
制作 ar -cr libxxx.a xxx1.o xxx2.o xxx3.o ... 编译 gcc main.c -l xxx [-L 库路径] (如果不加-L则在标准库路径下查找) 运行 ./a.out
LINUX系统中动态链接库的创建与使用 大家都知道,在WINDOWS系统中有很多的动态链接库(以.DLL为后缀的文件,DLL即Dynamic Link Library)。这种动态链接库,和静态函数库不同,它里面的函数并不是执行程序本身的一部分,而是根据执行程序需要按需装入,同时其执行代码可在多个执行程序间共享,节省了空间,提高了效率,具备很高的灵活性,得到越来越多程序员和用户的青睐。