1

我有以下代码,它只是从当前目录加载库 test.so 并version在该库中执行函数。应该返回的是一个字符串。相反,返回的是堆栈中的垃圾(可能是指针位置?)。有谁知道为什么以下代码会失败。

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

int main(int argc, char **argv){
    void *handler;
    char *(*version);
    char *error;

    handler = dlopen("./test.so", RTLD_LAZY);
    if(!handler){
        fprintf(stderr, "%s\n", dlerror());
        exit(EXIT_FAILURE);
    }

    dlerror(); //Flushes any existing error

    *(void **)(&version) = dlsym(handler, "version");

    if((error = dlerror()) != NULL){
        fprintf(stderr, "%s\n", error);
        exit(EXIT_FAILURE);
    }
    printf("%s\n", version);
    dlclose(handler);
    exit(EXIT_SUCCESS);
}
4

3 回答 3

4

更改声明:

char *(*version); // this is not a function pointer

到:

char *(*version)(); // but this is

然后,更改行:

printf("%s\n", version);

到:

printf("%s\n", version());
于 2012-04-29T18:24:56.717 回答
3

dlsym 只返回一个函数指针。您仍然需要实际调用它,您可以通过将 (void*) 强制转换为适当类型的函数指针并调用它来实现。

于 2012-04-29T18:10:40.750 回答
2

您的代码中有两个错误:

: 它的声明version是指向代码中 char 的指针的指针,这导致您在以下位置进行了奇怪的转换:

*(void **)(&version) = dlsym(handler, "version");

而是使用指向函数的指针返回指向 char 的指针,如下所示:

char *(*version)();

并使用常规分配:

version = dlsym(handler, "version");

当您打印结果时,您没有调用该函数。在 C 中,只写函数名会返回它的地址,所以version&version是等价的。你的代码应该是这样的:

printf("%s\n", version());
于 2012-04-29T18:36:18.340 回答