1. 基本原理
- 正常情况下,可执行文件的动态符号表中只包含了被链接的共享库中需要被外部引用的符号。 -rdynamic 参数改变了这一行为,它使得链接器把所有符号(包括函数和全局变量)都添加到动态符号表中。
2. 使用场景示例 - 假设你正在编写一个程序,它有一个主模块 main.c 和一个插件模块 plugin.c ,通过动态加载插件的方式来扩展程序功能。
- 主程序(main.c)
#include <stdio.h>
#include <dlfcn.h>
void my_function_in_main() {
printf(“This is a function in main program.\n”);
}
int main() {
void *handle;
void (*plugin_function)(void);
char *error;
handle = dlopen("./plugin.so", RTLD_LAZY);
if (!handle) {
fprintf(stderr, "%s\n", dlerror());
return 1;
}
// 尝试获取插件中的函数指针,该函数可能会调用主程序中的函数
plugin_function = (void (*)(void))dlsym(handle, "plugin_function");
if ((error = dlerror())!= NULL) {
fprintf(stderr, "%s\n", error);
return 1;
}
// 调用插件中的函数
plugin_function();
dlclose(handle);
return 0;
}
- 插件程序(plugin.c)
#include <stdio.h>
extern void my_function_in_main();
void plugin_function() {
printf(“This is a function in plugin.\n”);
my_function_in_main();
}
- 编译插件时使用 gcc -shared -fPIC plugin.c -o plugin.so 。
- 如果编译主程序时不使用 -rdynamic ,在运行时,当插件尝试调用主程序中的 my_function_in_main 函数时,可能会出现找不到符号的错误。
- 但是,当编译主程序时使用 gcc -rdynamic main.c -o main ,主程序中的所有符号(包括 my_function_in_main )都会被添加到动态符号表中,这样插件就能够正确地链接并调用主程序中的函数。这是因为 -rdynamic 参数使得主程序的符号在动态加载插件的环境下也能够被正确解析。