当加载的共享库经由功能dlopen()打开,是有办法为它调用函数在主程序?

有帮助吗?

解决方案

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听到,它也将使图书馆和主程序之间的吸尘器通信(你有什么可以称之为而不是精确的控制),但它也需要更家务管理。

其他提示

是的,如果你提供你的库中的指针指向功能,我敢肯定,图书馆将能够运行/在主程序执行功能。

下面是一个例子,并没有编译它所以要小心)

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

dlopen()功能,如通过@litb讨论的,主要是提供在使用ELF格式对象文件系统。这是相当强大的,可以让你控制由装载库引用的符号是否能够从主程序满意,一般不会让他们满意。并非所有的共享库加载的系统一样灵活 - 要知道,如果涉及到移植代码

通过@hhafez概述的回调机制现在工作,在该代码中的扭结理顺。

scroll top