1

I have the following code which simply loads the library test.so from the current directory and executes the version function within that library. What should be returned is a string. What is instead returned is junk from the stack(a pointer location maybe?). Does anyone have any idea why the following code would be failing.

#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

コードに 2 つのエラーがあります。

の宣言version: it は、コード内の 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 に答える