当通过函数打开共享库时dlopen()
,有没有办法在主程序中调用函数?
Nikron
问问题
5484 次
3 回答
24
dlo.c (lib) 的代码:
#include <stdio.h>
// function is defined in main program
void callb(void);
void test(void) {
printf("here, in lib\n");
callb();
}
编译
gcc -shared -olibdlo.so dlo.c
这里是主程序的代码(从 dlopen 手册页复制,并调整):
#include <stdio.h>
#include <stdlib.h>
#include <dlfcn.h>
void callb(void) {
printf("here, i'm back\n");
}
int
main(int argc, char **argv)
{
void *handle;
void (*test)(void);
char *error;
handle = dlopen("libdlo.so", RTLD_LAZY);
if (!handle) {
fprintf(stderr, "%s\n", dlerror());
exit(EXIT_FAILURE);
}
dlerror(); /* Clear any existing error */
*(void **) (&test) = dlsym(handle, "test");
if ((error = dlerror()) != NULL) {
fprintf(stderr, "%s\n", error);
exit(EXIT_FAILURE);
}
(*test)();
dlclose(handle);
exit(EXIT_SUCCESS);
}
构建
gcc -ldl -rdynamic main.c
输出:
[js@HOST2 dlopen]$ LD_LIBRARY_PATH=. ./a.out
here, in lib
here, i'm back
[js@HOST2 dlopen]$
该-rdynamic
选项将所有符号放入动态符号表(映射到内存)中,而不仅仅是使用符号的名称。在这里进一步阅读。当然,您也可以提供定义库和主程序之间接口的函数指针(或函数指针的结构)。这实际上是我可能会选择的方法。我从其他人那里听说,-rdynamic
在 Windows 中做到这一点并不容易,而且它还可以使库和主程序之间的通信更清晰(您可以精确控制可以调用的内容),但它还需要更多家政。
于 2008-12-25T01:42:17.723 回答
4
是的,如果您为您的库提供指向该函数的指针,我确信该库将能够在主程序中运行/执行该函数。
这是一个例子,还没有编译所以要小心;)
/* in main app */
/* define your function */
int do_it( char arg1, char arg2);
int do_it( char arg1, char arg2){
/* do it! */
return 1;
}
/* some where else in main app (init maybe?) provide the pointer */
LIB_set_do_it(&do_it);
/** END MAIN CODE ***/
/* in LIBRARY */
int (*LIB_do_it_ptr)(char, char) = NULL;
void LIB_set_do_it( int (*do_it_ptr)(char, char) ){
LIB_do_it_ptr = do_it_ptr;
}
int LIB_do_it(){
char arg1, arg2;
/* do something to the args
...
... */
return LIB_do_it_ptr( arg1, arg2);
}
于 2008-12-25T01:35:28.863 回答
1
正如@litb 所讨论的,该dlopen()
功能主要在使用 ELF 格式目标文件的系统上提供。它相当强大,可以让你控制加载的库引用的符号是否可以从主程序中得到满足,并且通常会让它们得到满足。并非所有的共享库加载系统都如此灵活——请注意移植代码。
@hhafez 概述的回调机制现在可以正常工作,因为代码中的问题已经解决。
于 2008-12-25T06:22:36.707 回答