c - 使用 libdl API 调用打开共享库的区别

标签 c linker shared-libraries loader

请阐明调用这两者的区别,并建议我哪个在性能和效率方面更好。

handle = dlopen("libxx.so", RTLD_GLOBAL| RTLD_NOW);
dlsym(handle, "func"); 

const char* dlfunc = dlsym(RTLD_DEFAULT, "func");

这个程序对我有用,并给出了一个有效的指针地址:

#define _GNU_SOURCE
#include <dlfcn.h>
#include <stdio.h>
int main() {
    /* void* handle = dlopen("libXt.so", RTLD_GLOBAL| RTLD_NOW);
    dlsym(handle, "XtStrings"); */
    const char* dlfunc = dlsym(RTLD_DEFAULT, "XtStrings");
    if(!dlfunc) {
        fprintf(stderr, "--- %s\n", dlerror());
    } else {
        printf("DEFAULT: %p\n", dlfunc);
        return;
    }
    dlfunc = dlsym(RTLD_NEXT, "XtStrings");
    if(!dlfunc) fprintf(stderr, "--- %s\n", dlerror());
    printf("NEXT: %p\n", dlfunc);
}

编译使用:gcc -ldl -L/usr/lib/x86_64-linux-gnu -lXt file.c

最佳答案

您的示例代码都没有多大用处,并且您的问题无法得到回答,也不是“更好”,因为您的两个代码片段做了不同的事情,例如您的第一个代码段加载了一个额外的共享库,而您的第二个代码段则没有。

dlopen() 允许您加载共享库。

dlsym() 允许您获取指向共享库或当前加载的代码(当前可执行文件+当前任何共享库)中符号的指针。符号可以是例如函数或变量。

下面是加载共享库并调用该共享库中具有原型(prototype) void func(void) 的函数的示例

void *handle = dlopen("libxx.so", RTLD_GLOBAL| RTLD_NOW); //load the shared library
void (*func_ptr)(void)  = dlsym(handle, "func");  //get a pointer to the "func" symbol
func_ptr(); //call the function through our function pointer

下面是使用 dlsym 获取指向当前加载的可执行文件(或任何当前链接到共享库)中的函数的指针的示例。

void (*func_ptr)(void)  = dlsym(RTLD_DEFAULT, "func");  //get a pointer to the "func" symbol
func_ptr(); //call the function through our function pointer

后面的代码可以通过直接调用函数来完成:

  func();

关于c - 使用 libdl API 调用打开共享库的区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24301281/

相关文章:

c++ - 通过 objdump 链接没有头文件的 so 库

Android 和链接库

用于生成 FCGI 服务器的 C API?

c - stm32 上的半主机

compilation - 使用 LINK.EXE 和 C2.EXE 手动编译 VB6 项目

c++ - 使用 ncurses 时未定义对 `stdscr' 的引用

c - C 程序中文本文件的 fscanf 和 fprintf 更改的值

c - 在 Linux 中递归计算目录的最快 C 代码(无文件)

c++ - 链接具有内联函数的静态库时出现问题

c - 将静态库链接到动态库时删除死代码