加载动态链接库,首先为共享库分配物理内存,然后在进程对应的页表项中建立虚拟页和物理页面之间的映射。你可以认为系统中存在一种引用计数机制, 每当一个进程加载了共享库(在该进程的页表中进行一次映射),引用计数加一;一个进程显式卸载(通过dlclose等)共享库或进程退出时,引用计数减 一,当减少到0时,系统卸载共享库。

#include <dlfcn.h>

相关函数介绍

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

void *dlopen (const char *filename, int flag); flag:分为这两种 RTLD_NOW:在dlopen返回前,解析出全部没有定义的符号,解析不出来返回NULL。 RT_GLOBAL:动态库定义的符号可被其后打开的其他库解析。 RT_LOCAL:和上面相反,不能被其他库解析。默认。 RTLD_LAZY:暂缓决定,等有需要时再解出符号 打开错误返回NULL 成功,返回库引用 dlopen用于打开指定名字(filename)的动态链接库(最好文件绝对路径),并返回操作句柄。

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

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

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

int dlclose (void *handle); returns 0 on success, and nonzero on error. dlclose用于关闭指定句柄的动态链接库,只有当此动态链接库的使用计数为0时,才会真正被系统卸载。

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

const char *dlerror(void); 当动态链接库操作函数执行失败时,dlerror可以返回出错信息,返回值为NULL时表示操作函数执行成功。
#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);  
	return 0;  

编译动态库命令:

g++ -o libtest.so -rdynamic -shared -fPIC test.cpp

编译主程序命令:

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

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

一、库文件的搜索路径: 1、在配置文件/etc/ld.so.conf中指定动态库搜索路径(需要添加其它库文件的路径,在文件的最后添加具体的路径即可 [ 如:/usr/local/lib ],添加后保存退出,然后在命令行ldconfig 2、通过环境变量LD_LIBRARY_PATH指定动态库搜索路径(当通过该环境变量指定多个动态库搜索路径时,路径之间用冒号":"分隔) 3、在编译目标代码时指...
库的存在极大的提高了C/C++程序的复用性,但是库对于初学者来说有些难以驾驭,本文从Linux的角度浅谈Linux下的静态库、动态库动态加载库。   Linux库类型   Linux下可以创建两种类型的库:   1、静态库(.a): 在链接期间被应用程序直接链接进可执行文件   2、动态链接库(.so): 动态库还分为两种用法: a) 应用程序运行期间链接动态库,但是在编译期间声明动态库的存在,也是说这种动态库必须在编译时对编译器可见,但编译器却不将此种库编译进可执行文件; b) 在运行期间,动态加载和卸载的库,使用动态加载方法加载。这种库的形式跟动态链接没有本质区别,区别是在调用
这里写自定义目录标题欢迎使用Markdown编辑器一. 生成.so库二. 调用.so库参考链接 欢迎使用Markdown编辑器 你好! 这是你第一次使用 Markdown编辑器 所展示的欢迎页。如果你想学习如何使用Markdown编辑器, 可以仔细阅读这篇文章,了解一下Markdown的基本语法知识。 一. 生成.so库 c++工程目录 我的c++工程myProject目录结构如下: 1. include -----det.h -----ut.h 2. src -----det.c
INCLUDEPATH += 库的头文件路径 LIBS += -L PATH -lLIB,PATH是so库所在路径,LIB是库的名字(-L是库路径,-l是库名字,例如库文件是libReceiptPrint.so,后面应添加-lReceiptPrint) collect2:ld returned 1 exit status解决方案:没有正确加载库,检测库路径,32位还是64位,库是debug版还是release版 INCLUDEPATH += /home/chw/HSCompany/HardWareT
本文将win、linux加载、卸载动态库,并从动态库链接模块中获取类实例或函数地址等封装成统一的API接口,并集成在dllLoad.h/dllLoad.cpp中实现。构建一个注册类RegisterM,内置一个map容器,用来装载加载动态库模块,并统一提供模块索引、及从模块中实现类实例获取、删除、函数地址获取等功能。 在动态库实现方面,提供一个虚拟元类MetaObject,然后在库的cpp文件中建立子类继承该类,实现其具体功能,并在cpp文件中直接提供函数API
引子(ELF文件格式) 在分析Linux动态库加载过程之前,首先介绍Linux系统中的可执行与可链接格式(Executable and Linkable Format,ELF),该文件格式是UNIX系统实验室(USL)作为应用程序二进制接口(Application Binary Interface,ABI)而开发和发布的,也是Linux的主要可执行文件格式,Linux下的执行体、so、o和bin等文件都符合该格式。 ELF文件由4部分组成,分别是ELF头...
项目中经常遇见两个库不兼容,而要调用两个动态库的时候,有一个选择就是以动态加载的方式加载这个库. 看看头文件的介绍 dlfcn.h - dynamic linking # 动态链接 常用的方法如下: #include <stdio.h> #include <stdlib.h> #include <dlfcn.h> #inc...
Linux中,Qt可以通过使用QLibrary类来加载动态链接库(.so文件)。QLibrary类提供了一个简单的接口,可以在运行时动态加载和卸载共享库。以下是加载.so文件的步骤: 1. 在Qt项目中包含QLibrary头文件。 2. 创建QLibrary对象并指定.so文件的路径。 3. 使用QLibrary对象的load()函数加载.so文件。 4. 使用QLibrary对象的resolve()函数获取.so文件中的函数指针。 5. 使用函数指针调用.so文件中的函数。 6. 使用QLibrary对象的unload()函数卸载.so文件。 例如,以下代码演示了如何加载调用一个名为libtest.so的动态库中的函数: #include <QLibrary> #include <QDebug> int main() // 创建QLibrary对象并指定.so文件的路径 QLibrary lib("libtest.so"); // 加载.so文件 if (lib.load()) { // 获取.so文件中的函数指针 typedef int (*testFunc)(int); testFunc func = (testFunc)lib.resolve("test"); // 调用.so文件中的函数 if (func) { int result = func(5); qDebug() << "Result: " << result; else { qDebug() << "Failed to resolve function."; // 卸载.so文件 lib.unload(); else { qDebug() << "Failed to load library."; return ;