☰
Linux动态加载并调用动态库(.so)实现方式
2026/9/27 1:06:46 网站建设 项目流程

念

加载动态链接库,首先为共享库分配物理内存,然后在进程对应的页表项中建立虚拟页和物理页面之间的映射。

你可以认为系统中存在一种引用计数机制, 每当一个进程加载了共享库(在该进程的页表中进行一次映射),引用计数加一;

一个进程显式卸载(通过dlclose等)共享库或进程退出时,引用计数减 一,当减少到0时,系统卸载共享库。

头文件

1

#include <dlfcn.h>

相关函数介绍

(1)打开动态链接库:dlopen

1

2

3

4

5

6

7

8

9

10

11

12

13

函数原型

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

flag:分为这两种

RTLD_NOW:在dlopen返回前,解析出全部没有定义的符号,解析不出来返回NULL。

RT_GLOBAL:动态库定义的符号可被其后打开的其他库解析。

RT_LOCAL:和上面相反,不能被其他库解析。默认。

RTLD_LAZY:暂缓决定,等有需要时再解出符号

返回值:

打开错误返回NULL

成功,返回库引用

dlopen用于打开指定名字(filename)的动态链接库(最好文件绝对路径),并返回操作句柄。

(2)取函数执行地址:dlsym

1

2

3

函数原型

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

dlsym根据动态链接库操作句柄(handle)与符号(symbol),返回符号对应的函数的执行代码地址。

(3)关闭动态链接库:dlclose

1

2

3

4

函数原型

int dlclose (void *handle);

returns 0 on success, and nonzero on error.

dlclose用于关闭指定句柄的动态链接库,只有当此动态链接库的使用计数为0时,才会真正被系统卸载。

(4)动态库错误函数:dlerror

1

2

3

函数原型

const char *dlerror(void);

当动态链接库操作函数执行失败时,dlerror可以返回出错信息,返回值为NULL时表示操作函数执行成功。

示例

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

#include <stdio.h>

#include <dlfcn.h>

int main(int argc, char **argv) {

void *handle;

double (*cosine)(double);

char *error;

handle = dlopen ("/tmp/libtest.so", RTLD_LAZY);

if(!handle) {

fprintf (stderr,"%s ", dlerror());

exit(1);

}

cosine = (double(*)(double))dlsym(handle,"cos");

if((error = dlerror()) != NULL) {

fprintf (stderr,"%s ", error);

exit(1);

}

printf("%f ", (*cosine)(2.0));

dlclose(handle);

return0;

}

编译

编译动态库命令:

1

g++ -o libtest.so -rdynamic -shared -fPICtest.cpp

编译主程序命令:

1

g++ -o mainTest mainTest.cpp -rdynamic -ldl

注意要加-ldl 和 -rdynamic 链接选项

总结

以上为个人经验,希望能给大家一个参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询