Linux .so库的使用

Linux .so库的使用,第1张

新建一个sort.c文件,写一个最简单的排序

使用 gcc -o libsort.so -fPIC -shared sort.c 产生libsort.so库。

.so库有两种调用方法:

新建main.c文件:

使用命令 gcc -o main main.c -lsort -L. 编译。

新建main2.c文件:

使用命令 gcc -o main2 main2.c -ldl 编译。动态加载.so库的话需要-ldl。

运行./main2后输出递增序列,调用成功。

在WINDOWS系统中有很多的动态链接库(以.DLL为后缀的文件,DLL即Dynamic Link Library)。这种动态链接库,和静态函数库不同,它里面的函数并不是执行程序本身的一部分,而是根据执行程序需要按需装入,同时其执行代码可在多个 执行程序间共享,节省了空间,提高了效率,具备很高的灵活性。同样,LINUX的也具备类似的动态链接库,而且为数不少。在/lib目录下,就有许多以.so作后缀的文件,这就是LINUX系统应用的动态链接库,只不过与WINDOWS叫法不同,它叫so,即Shared Object,共享对象。(在LINUX下,静态函数库是以.a作后缀的) X-WINDOW作为LINUX下的标准图形窗口界面,它本身就采用了很多的动态链接库(在/usr/X11R6/lib目录下),以方便程序间的共享, 节省占用空间。flash只是一个插件,在windows中就是一个ocx的链接库方式(和dll略有不同),因此linux中一旦你了一个共享函数库,你还需要安装它。其实简单的方法就是拷贝 \x0d\x0a你的库文件到指定的标准的目录(例如/usr/lib),然后运行ldconfig。 \x0d\x0a如果你没有权限去做这件事情,例如你不能修改/usr/lib目录,那么 \x0d\x0a你就只好通过修改你的环境变量来实现这些函数库的使用了。首先, \x0d\x0a你需要创建这些共享函数库;然后,设置一些必须得符号链接,特别 \x0d\x0a是从soname到真正的函数库文件的符号链接,简单的方法就是运行ldconfig: \x0d\x0aldconfig -n directory_with_shared_libraries \x0d\x0a然后你就可以设置你的LD_LIBRARY_PATH这个环境变量,它是一个以逗号 \x0d\x0a分隔的路径的集合,这个可以用来指明共享函数库的搜索路径。例如 \x0d\x0a,使用bash,就可以这样来 \x0d\x0a启动一个程序my_program: \x0d\x0aLD_LIBRARY_PATH=.LD_LIBRARY_PATH my_program

实例代码(soTest.c):

1 #include <stdio.h>

2 #include <dlfcn.h>

3

4 int main(int argc, char *argv[]){

5 void * libm_handle = NULL

6 float (*cosf_method)(float)

7 char *errorInfo

8 float result

9

10 // dlopen 函数还会自动解析共享库中的依赖项。这样,如果您打开了一个依赖于其他共享库的对象,它就会自动加载它们。

11 // 函数返回一个句柄,该句柄用于后续的 API 调用

12 libm_handle = dlopen("libm.so", RTLD_LAZY )

13 // 如果返回 NULL 句柄,表示无法找到对象文件,过程结束。否则的话,将会得到对象的一个句柄,可以进一步询问对象

14 if (!libm_handle){

15 // 如果返回 NULL 句柄,通过dlerror方法可以取得无法访问对象的原因

16 printf("Open Error:%s.\n",dlerror())

17 return 0

18 }

19

20 // 使用 dlsym 函数,尝试解析新打开的对象文件中的符号。您将会得到一个有效的指向该符号的指针,或者是得到一个 NULL 并返回一个错误

21 cosf_method = dlsym(libm_handle,"cosf")

22 errorInfo = dlerror()// 调用dlerror方法,返回错误信息的同时,内存中的错误信息被清空

23 if (errorInfo != NULL){

24 printf("Dlsym Error:%s.\n",errorInfo)

25 return 0

26 }

27

28 // 执行“cosf”方法

29 result = (*cosf_method)(0.0)

30 printf("result = %f.\n",result)

31

32 // 调用 ELF 对象中的目标函数后,通过调用 dlclose 来关闭对它的访问

33 dlclose(libm_handle)

34

35 return 0

36 }

在这个例子中主要是调用了 math 库(libm.so)中的“cosf”函数,dlopen函数的第二个参数表示加载库文件的模式,主要有两种:RTLD_LAZY 暂缓决定,等有需要时再解出符号;RTLD_NOW 立即决定,返回前解除所有未决定的符号。另外记得引用包含API的头文件“#include <dlfcn.h>”(^_^)。


欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/yw/6269499.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-03-19
下一篇 2023-03-19

发表评论

登录后才能评论

评论列表(0条)

保存