Неопределенный символ для dlsym в С++

У меня есть одна программа на С++, которую я хочу загрузить в свою текущую программу на С++. Ниже приведен фрагмент

Файл: a.cpp

    #include<bits/stdc++.h>
    using namespace std;

    void abc() { 
      cout << "This is abc" << endl;
    }

Файл : mainFile.cpp

    #include <bits/stdc++.h>
    #include <dlfcn.h>

    int main(int argc, char **argv) {
      system("g++ -fpic -shared -ldl -o a.so a.cpp"); 
      void *lib = dlopen("./a.so", RTLD_NOW);
       if (!lib) {
         printf("dlopen failed: %s\n", dlerror());
         return 1;
      }
      void (*f)();
      f = (void (*)()) dlsym(lib, "abc");
      if (f) {
          f();
      } else {
          printf("dlsym for f1 failed: %s\n", dlerror());
      }

      dlclose(lib);
      return 0;
    }

Я компилирую со следующими командами

    g++ -w mainFile.cpp -ldl -o mainFile && ./mainFile

Выход:

    dlsym for f1 failed: ./a.so: undefined symbol: abc

Пожалуйста помоги.

Я компилирую в Ubuntu 16.04 с версией g++ g++ (Ubuntu 5.4.0-6ubuntu1~16.04.12) 5.4.0 20160609

НАБЛЮДЕНИЕ Странно то, что когда у меня есть вышеуказанный файл a.cpp как a.c и только с заголовком stdio.h, а также с флагом -fpermissive, программа компилируется, и я получаю вывод как This is abc. Я не понимаю, почему версия CPP не работает. Причина, по которой я не могу использовать CPP (или, скорее, не решаюсь пойти по маршруту .C), заключается в том, что мой проект требует концепции OOPS, и я должен использовать классы в файле библиотеки. Приведенный выше пример предназначен только для упрощения цели. Примечание. Я следил за следующими ссылками, но ничего не помогло.

  1. Можете ли вы динамически компилировать и связывать/загружать код C в программу C?
  2. неопределенная ссылка на `dlopen' после обновления Ubuntu
  3. C неопределенный символ dlsym

person Pradeep Mahato    schedule 24.01.2020    source источник
comment
попробуйте определить void abc как extern "C"   -  person Iłya Bursov    schedule 24.01.2020
comment
stackoverflow .com/questions/1041866/   -  person Iłya Bursov    schedule 24.01.2020
comment
И stackoverflow.com/questions/ 18096596/   -  person Antti Haapala    schedule 24.01.2020
comment
Всем спасибо. использование extern C работало.   -  person Pradeep Mahato    schedule 24.01.2020


Ответы (1)


В C++ имена искажены, то есть имя символа в библиотеке не просто abc. Вместо этого у него есть дополнительные символы (украшения), которые описывают аргументы и т. д. этой функции. Вот почему вы не найдете функцию по имени abc.

У вас есть два варианта:

  1. Найдите искаженное имя (которое может быть сложным/непереносимым, поскольку изменение зависит от компилятора).
  2. Объявите функцию abc() как extern "C" { void abc(); }. Это запрашивает C-связь для функции и, таким образом, предотвращает искажение имени.

Смотрите также множество указателей, которые вы получили в комментариях.

person Daniel Junglas    schedule 24.01.2020
comment
Спасибо @Daniel !! Вариант 1 не казался практичным для чего-то большего, чем практические упражнения. Я попробовал вариант 2, и это сработало. - person Pradeep Mahato; 24.01.2020