dlsym returns 无效指针

dlsym returns an invalid pointer

我有一个像这样的动态链接模块:

int func() {
    return 5;
}

extern int(*func_p)() = func;

还有一个加载函数指针的主函数:

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

int main() {
    void *module = dlopen("/tmp/mod/mod.so", RTLD_NOW);
    if (!module)
  {
     printf("Cannot load module: %s\n", dlerror());
     return 1;
  }

    typedef int(*func_f)();
    func_f func;

    func = dlsym(module, "func_p");
    char *error = dlerror();
    if (error)
{
   printf("Cannot find init in module: %s\n", error);
   return 1;
}

    printf("Func returns: %i\n", func());
}

我有什么方法可以使它工作还是完全超出范围?

我可以手动“解析”函数指针吗?

在C中,func是一个函数,func_p是一个指向函数的指针。当名称作为 dlsym 的参数给出时,dlsym returns 命名事物的地址。因此,对于 "func",它 returns 名为 func 的函数的地址。对于 "func_p",它 returns 名为 func_p 的指针的地址。

当然不能用指针的地址func_p来调用函数。为此,您需要指针的值。

这些都应该有效:

// Get address of function.
int (*func)() = (int (*)()) dlsym(module, "func");

// Call function.
func();
// Get address of pointer to function.
int (**p)() = dlsym(module, "func_p");

// Deference to get pointer to function, then call function.
(*p)();

后者是不必要的,除非该函数在外部不可见。只要func能被dlsym查到,前者就够了。

另请注意,有关链接器和相关内容的文档可能 dlsym 指的是符号的值,但是,对于这些类型的符号,这些值是符号所指内容所在的地址.也就是说,对于 C,func 是一个函数,func_p 是一个指针,但是对于链接器,func 是它在目标模块中找到的某个名称,它的“值”是它在内存中的地址,类似地 func_p 的值是它的地址。阅读此类文档时,您必须注意链接器和符号解析器执行不同的任务并以不同于 C 编译器的方式处理名称。