dlopen / dlsym: ошибка при получении указателя на функцию

Я пытаюсь получить указатель на функцию с помощью dlopen и dlsym, однако мне не удалось заставить его работать правильно. Ошибка при попытке выполнить вызов dlsym. Ниже мой код.

Любая помощь, пожалуйста?

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

int test() {
    printf("%s", "test()");
    return 123;
}

int main() {
    char * functionname = "test";
    void* handle = dlopen(NULL,RTLD_LAZY|RTLD_GLOBAL);
    if (!handle) {
        fprintf(stderr, "Couldn't open handle: %s\n",
            dlerror());
        exit(1);
    }

    int (*fun)() = (int (*)())dlsym(handle, functionname);
    if (fun == NULL) { 
        fprintf(stderr, "Couldn't find function: %s\n",functionname); 
        exit(1);
    }
    int a = fun();
    printf("result: %d \n", a);
}

person Jacob    schedule 21.03.2014    source источник
comment
Что дает вам уверенность в том, что символ test существует в библиотеке?   -  person mah    schedule 21.03.2014
comment
не должно ли оно существовать, как я определил в основном? From dlopen Если filename является указателем NULL, то возвращаемый дескриптор предназначен для основной программы.   -  person Jacob    schedule 21.03.2014
comment
Понятно, я неправильно понял вопрос; Я не заметил, что вы хотели получить символ из собственного исполняемого файла. Я не уверен, что это сделано так, как вы пытаетесь ... что произойдет, если вы будете искать символ через dlsym(NULL, function name);?   -  person mah    schedule 21.03.2014
comment
То же самое происходит, если я вызываю dlsym (NULL, ..), хотя это тоже не имеет смысла. dlsym ожидает дескриптор, полученный вызовом dlopen.   -  person Jacob    schedule 21.03.2014
comment
Другие допустимые дескрипторы для использования dlsym включают RTLD_SELF и RTLD_MAIN_ONLY, оба из которых могут быть полезны. Я думал (кажется, ошибочно), что NULL будет таким же, как запрос на поиск символа в основном исполняемом файле.   -  person mah    schedule 21.03.2014
comment
Вы случайно не знаете, где они определены RTLD_SELF и RTLD_MAIN_ONLY? не могу их нигде найти. Я также попытался использовать их с тем же результатом, однако есть два специальных псевдо-дескриптора, RTLD_DEFAULT и RTLD_NEXT. Первый найдет первое вхождение нужного символа, используя порядок поиска в библиотеке по умолчанию. Последний найдет следующее вхождение функции в порядке поиска после текущей библиотеки.   -  person Jacob    schedule 21.03.2014
comment
Я нашел их в моем dlfcn.h (вместе с DEFAULT и NEXT). RTLD_DEFAULT также должен работать на вас. (Я предполагаю, что SELF и MAIN_ONLY могут быть специфичными для OS X / iOS.). RTLD_NEXT используется, когда один и тот же символ существует в нескольких библиотеках и нужно найти следующий.   -  person mah    schedule 21.03.2014
comment
хорошо, хорошо. default и next дают одинаковый результат. Например. он не может найти символ.   -  person Jacob    schedule 21.03.2014
comment
При сборке вам может потребоваться применить некоторые параметры компоновщика. См. stackoverflow.com/questions/6292473/, чтобы попробовать.   -  person mah    schedule 21.03.2014


Ответы (1)


Возможно, вам нужно указать компоновщику, чтобы символы экспортировались как динамические. С gcc вы должны использовать -rdynamic.

Вы можете проверить экспортированные динамические символы с помощью objdump -T.

person Sigi    schedule 21.03.2014