我即将使用dlopen()打开共享对象。如果共享对象,是否需要包含相应的标头?

时间:2013-12-02 06:01:13

标签: header dlopen

我必须使用dlopen()并在我的代码中访问共享对象中的函数。我是否需要包含共享对象的相应功能的标题?

1 个答案:

答案 0 :(得分:1)

由于dlopen()和dlsym()的运行方式,我看不出它会如何实现。非常粗略地说,dlopen()将库二进制文件复制到程序空间中,并将其导出符号的地址(即全局函数和变量)添加到程序的符号表中。

由于库在编译时没有链接到您的程序,因此您的代码无法知道在运行时添加的这些新函数的指令地址。访问运行时动态链接符号的唯一方法是通过从dlsym()获得的指针。

您必须为要使用的每个库定义创建一个函数指针。如果你想像常规函数一样调用它们,你可以用C语言手动typedef函数指针的类型定义,指定它们的参数和返回值,然后就像常规函数一样调用指针。但请注意,您必须手动定义所有这些。包括库头没有帮助。

在C ++中,我认为由于更严格的标准,在typedef指针中存储dlsym()输出存在问题,但这应该适用于C:

addlib.c(libaddlib.dylib):

int add(int x, int y) {
    return x+y;
}

myprogram.c:

#include <stdio.h>
#include <dlfcn.h>

typedef int (*add_t)(int, int);

int main() {
    void *lib_handle;
    add_t add;  // call this anything you want...it's a pointer, it doesn't care

    lib_handle = dlopen("libaddlib.dylib", RTLD_NOW);
    if (lib_handle == NULL) {
        // error handling
    }

    add = (add_t)dlsym(lib_handle, "add");
    if (add == NULL) {
        // error handling
    }

    printf("Sum is %d\n", add(17, 23));

    dlclose(lib_handle);    // remove library from address space
    return 0;
}

(更新:我编译了dylib和myprogram ......它按预期工作。)