我有一个我实现的共享库,并希望 .so 调用在加载库的主程序中实现的函数。
假设我有 main.c(可执行文件),其中包含:
void inmain_function(void*);
dlopen("libmy.so");
在 my.c(libmy.so 的代码)中,我想调用 inmain_function
:
inmain_function(NULL);
共享库如何调用 inmain_function
而不管 inmain_function
是在主程序中定义的。
注意:我想从 my.c 调用 main.c 中的一个符号,而不是相反,这是常见的用法。
最佳答案
您有两个选项,您可以从中选择:
选项 1:从可执行文件中导出所有符号。
这是一个简单的选项,只是在构建可执行文件时,添加一个标志 -Wl,--export-dynamic
。这将使所有函数都可用于库调用。
选项 2:创建一个包含函数列表的导出符号文件,并使用 -Wl,--dynamic-list=exported.txt
。这需要一些维护,但更准确。
演示:简单的可执行文件和动态加载的库。
#include <stdio.h>
#include <dlfcn.h>
void exported_callback() /*< Function we want to export */
{
printf("Hello from callback!\n");
}
void unexported_callback() /*< Function we don't want to export */
{
printf("Hello from unexported callback!\n");
}
typedef void (*lib_func)();
int call_library()
{
void *handle = NULL;
lib_func func = NULL;
handle = dlopen("./libprog.so", RTLD_NOW | RTLD_GLOBAL);
if (handle == NULL)
{
fprintf(stderr, "Unable to open lib: %s\n", dlerror());
return -1;
}
func = dlsym(handle, "library_function");
if (func == NULL) {
fprintf(stderr, "Unable to get symbol\n");
return -1;
}
func();
return 0;
}
int main(int argc, const char *argv[])
{
printf("Hello from main!\n");
call_library();
return 0;
}
库代码(lib.c):
#include <stdio.h>
int exported_callback();
int library_function()
{
printf("Hello from library!\n");
exported_callback();
/* unexported_callback(); */ /*< This one will not be exported in the second case */
return 0;
}
所以,首先构建库(这一步没有区别):
gcc -shared -fPIC lib.c -o libprog.so
现在构建导出所有符号的可执行文件:
gcc -Wl,--export-dynamic main.c -o prog.exe -ldl
运行示例:
$ ./prog.exe
Hello from main!
Hello from library!
Hello from callback!
导出的符号:
$ objdump -e prog.exe -T | grep callback
00000000004009f4 g DF .text 0000000000000015 Base exported_callback
0000000000400a09 g DF .text 0000000000000015 Base unexported_callback
现在导出列表(exported.txt
):
{
extern "C"
{
exported_callback;
};
};
构建并检查可见符号:
$ gcc -Wl,--dynamic-list=./exported.txt main.c -o prog.exe -ldl
$ objdump -e prog.exe -T | grep callback
0000000000400774 g DF .text 0000000000000015 Base exported_callback
关于c - 共享库 (.so) 如何调用在其加载程序代码中实现的函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17081131/