Динамическая загрузка общей библиотеки с помощью dlopen

Я пытаюсь загрузить TestCode.so с помощью dlopen. getNumber() — это функция, которую я хочу использовать из TestCode.so. Но когда я загружаю .so. Я не могу использовать функцию. Это дает ошибку сегментации.

Пример программы: TestHeader.hpp

#ifndef _HEADER_HPP
#define _HEADER_HPP

typedef struct
{
        int number;
} Test;

#endif

TestCode.cpp

#include "TestHeader.hpp"

extern "C" void getNumber( Test* tObj, int number)
{
        tObj->number = number;
}

main.cpp

#include "TestHeader.hpp"
#include <iostream>
#include <dlfcn.h>
#include <stdio.h>
int main() {
        using std::cout;
        using std::cerr;
        Test* tMainObj = NULL;    
        typedef int (*TestNumber)(Test*, int);

        void* thandle = dlopen("./TestCode.so", RTLD_LAZY);
        if (!thandle) {
                cerr << "Cannot load TestCode: " << dlerror() << '\n';
                return 1;
        }

        // reset errors
        dlerror();

        // load the symbols
        TestNumber getAge = (TestNumber) dlsym(thandle, "getNumber");
        const char* dlsym_error = dlerror();
        if (dlsym_error) {
                cerr << "Cannot load symbol getNumber: " << dlsym_error << '\n';
                return 1;
        }
        printf("Getting my age\n");
        int myAge = 25; 
        getAge(tMainObj,myAge);
        printf("My age from the so is: %d\n",tMainObj->number);

        dlclose(thandle);
}

Выход:

Получение ошибки сегментации моего возраста (дамп ядра)

Для компиляции и создания общей библиотеки. Я использовал следующую команду,

g++ -fPIC -c -Wall TestHeader.hpp
g++ -fPIC -c -Wall TestCode.cpp 
g++ -shared TestCode.o -o TestCode.so
g++ -fPIC -c -Wall main.cpp
g++ main.cpp -o main TestCode.o -ldl

Может ли кто-нибудь помочь мне понять эту часть? Заранее спасибо.


person Emma Roberts    schedule 25.06.2019    source источник
comment
где сегфолт? как вы скомпилировали библиотеку и свой код (какой компилятор, флаги и т. д.)?   -  person OznOg    schedule 25.06.2019
comment
Почему ваш typedef возвращает int, а функция void?   -  person Quimby    schedule 25.06.2019
comment
@OznOg, я добавил в вопрос   -  person Emma Roberts    schedule 25.06.2019
comment
@Quimby, спасибо, что заметили. Я исправил ошибку seg в строке tObj-›number = number   -  person Emma Roberts    schedule 25.06.2019


Ответы (1)


Причина в том, что вы никогда не выделяете объект Test. Указатель — NULL (используйте nullptr), поэтому
tObj->number = number; — это UB и, вероятно, segfault. Нет никаких причин для того, чтобы test был указателем.

Test tMainObj;getAge(&tMainObj,myAge); проще и выполняет свою работу.

person Quimby    schedule 25.06.2019
comment
@EmmaRoberts Если хотите, вы можете принять этот ответ, чтобы вопрос был отмечен как отвеченный. - person Quimby; 25.06.2019