一.先生成一个共享so库文件
// example.c
#include <stdio.h>
void hello() {
printf("Hello from the shared library!\n");
}
void test(int a)
{
printf("Test from the shared library! parameter is %d\n",a);
}
用命令生成so库文件
#编译共享库:
gcc -shared -fPIC -o libexample.so example.c
就会在目录下生成一个libexample.so文件
二.在主方法中执行该动态so库调用方法
int main() {
// ---- 加载动态so库文件
/**
* void* dlopen(const char* filename, int flag);
filename:要加载的共享库的路径(可以是绝对路径或相对路径)。如果值为 NULL,表示加载主程序(通常不使用该选项)。
flag:用于指定加载共享库的方式,可以是以下的一个或多个标志的组合:
RTLD_LAZY:延迟加载,即只有在调用符号时才进行解析。
RTLD_NOW:立即加载,即在加载时解析所有符号。
RTLD_GLOBAL:使库中的符号在其他共享库中可见(默认是 RTLD_LOCAL,即符号仅在当前库内部可见)。
RTLD_LOCAL:符号只对当前共享库可见。
*/
void* handle = dlopen("/demo_c/libexample.so", RTLD_LAZY);
/**
* 返回值:
成功时,dlopen 返回一个非 NULL 的指针,指向已加载的共享库的句柄。
失败时,返回 NULL,并且可以使用 dlerror() 函数获取错误信息。
*/
if (!handle)
{
// 如果加载失败,输出错误信息
fprintf(stderr, "Error loading library: %s\n", dlerror());
}
else
{
printf("libexample.so 库已经被成功加载!\n");
}
// 获取库中的函数
void (*hello)();
void (*test)(int);
// dlsym():用于查找共享库中某个符号(函数或变量)。
// 它返回一个指向该符号的指针,可以将其转换为合适的函数指针类型。
hello = dlsym(handle,"hello");
test = dlsym(handle,"test");
// 检查函数是否找到
if (!hello)
{
fprintf(stderr, "Error finding symbol: %s\n", dlerror());
dlclose(handle);
}
// 调用函数
hello();
test(10);
// 关闭已加载的共享库,释放资源。
dlclose(handle);
// ---------------------
}
输出以下内容
libexample.so 库已经被成功加载!
Hello from the shared library! -- 说明加载了libexample.so库文件中的 hello方法
Test from the shared library! parameter is 10 -- 说明加载了libexample.so库文件中的 test方法
三.说明
dlopen
的基本用法 void* dlopen(const char* filename, int flag); 参数: filename
:要加载的共享库的路径(可以是绝对路径或相对路径)。如果值为NULL
,表示加载主程序(通常不使用该选项)。 flag
:用于指定加载共享库的方式,可以是以下的一个或多个标志的组合:返回值: 成功时,RTLD_LAZY:延迟加载,即只有在调用符号时才进行解析。 RTLD_NOW:立即加载,即在加载时解析所有符号。 RTLD_GLOBAL:使库中的符号在其他共享库中可见(默认是 RTLD_LOCAL,即符号仅在当前库内部可见)。 RTLD_LOCAL:符号只对当前共享库可见。
dlopen
返回一个非NULL
的指针,指向已加载的共享库的句柄。 失败时,返回NULL
,并且可以使用dlerror()
函数获取错误信息。
dlsym()
:用于查找共享库中某个符号(函数或变量)。它返回一个指向该符号的指针,可以将其转换为合适的函数指针类型。void* dlsym(void* handle, const char* symbol);
dlclose()
:关闭已加载的共享库,释放资源。int dlclose(void* handle);
四.小结
- 使用
dlopen
动态加载共享库。 - 使用
dlsym
获取符号地址(如函数指针)。 - 使用
dlclose
卸载共享库,释放资源。
dlopen
和相关函数常用于插件系统、动态扩展等场景。