加载的库函数如何在主应用程序中调用符号?

加载共享库时,通过函数dlopen()打开,有没有办法在主程序中调用函数?

dlo.c代码(lib):

 #include  // 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  #include  #include  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选项将所有符号放在动态符号表(映射到内存中)中,而不仅仅是使用符号的名称。 在这里进一步了解它。 当然,您还可以提供定义库与主程序之间接口的函数指针(或函数指针结构)。 这实际上是我可能选择的方法。 我从其他人那里听说,在Windows中进行-rdynamic并不是那么容易,而且它还可以使库和主程序之间的通信更加清晰(你可以对可以调用的内容进行精确控制而不是),但它也是需要更多的家务。

是的,如果您为库提供指向该函数的指针,我确信该库将能够在主程序中运行/执行该函数。

这是一个例子,没有编译它所以要小心;)

 /* 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); } 

@litb讨论的dlopen()函数主要在使用ELF格式目标文件的系统上提供。 它function非常强大,可以让您控制加载库引用的符号是否可以从主程序中得到满足,并且通常可以让它们满足。 并非所有共享库加载系统都具有灵活性 – 请注意是否需要移植代码。

@hhafez概述的回调机制现在可以解决该代码中的问题。