Как получить указатель на функцию C внутри класса C ++? - PullRequest
2 голосов
/ 17 ноября 2011

В классе C ++ мне нужно вызывать функции из динамически загружаемой библиотеки.Я получаю указатели на функции следующим образом:

typedef void (*TDef_libfunc)(); // also tried extern "C" typedef void (*TDef_libfunc)();

my_libfunc = (TDef_libfunc)dlsym(thelibrary, "libfunc");

(загружена функция lib, я вижу ее в отладчике.)

my_libfunc объявлен как переменная-член следующим образом:

TDef_libfunc my_libfunc;

Внутри функции-члена этого класса я пытаюсь вызвать указатель на свою функцию следующим образом:

my_libfunc();

Но происходит сбой ... Я правильно делаю?Возможно ли иметь переменную-член, которая является указателем на функцию C?

1 Ответ

4 голосов
/ 18 ноября 2011

Простая библиотека, скомпилированная с использованием gcc (если вы компилируете g ++, вам нужно добавить extern "C").

// test-lib.c
// gcc -Wall -g -shared -fpic test-lib.c -o test-lib.so
#include <stdio.h>

void
libfunc()
{
    printf("Hello World - Message sent from the libfunc() function.\n");
}

Простая программа, которая загрузит вышеуказанную библиотеку (жестко запрограммированный путь и функция).

У меня была ошибка seg, потому что у меня был объявленный fn_ в качестве указателя.

// test-loadlib.cpp
// g++ -Wall -g test-loadlib.cpp -o test-loadlib -ldl
#include <iostream>
#include <dlfcn.h>

typedef void (*TDef_libfunc)(void);

class TestClass
{
public:
    TestClass() : lib_(NULL) , fn_(NULL) { }

    ~TestClass() { if (lib_ != NULL) dlclose(lib_); }

    bool
    load_library()
    {
        if ((lib_ = dlopen("./test-lib.so", RTLD_NOW)) == NULL)
            return false;

        // From man page, this is correct way to store function ptr.
        *(void**) (&fn_) = dlsym(lib_, "libfunc");
        if (fn_ == NULL)
        {
            dlclose(lib_);
            lib_ = NULL;
            return false;
        }
        return true;
    }

    void
    call_func()
    {
        if (fn_ != NULL)
            (*fn_)();
        else
            std::cout << "Function not loaded.\n";
    }

private:
    void*         lib_;
    TDef_libfunc  fn_;    // Don't include '*' - it will segfault.
};

int
main(int argc, char *argv[])
{
    TestClass  tc;

    if (tc.load_library())
        tc.call_func();
    else
        std::cout << "Failed to load library.\n";
    return 0;
}

Я протестировал и скомпилировал это в Ubuntu 10.04, используя компилятор из репозитория.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...