dynamic_cast перестал работать при использовании с dlopen/dlsym

Введение

Позвольте мне принести извинения заранее за долгий вопрос. Это столь коротко, как я мог сделать его, который, к сожалению, не очень короток.

Установка

Я определил два интерфейса, A и B:

class A // An interface
{
public:
  virtual ~A() {}

  virtual void whatever_A()=0;
};

class B // Another interface
{
public:
  virtual ~B() {}

  virtual void whatever_B()=0;
};

Затем у меня есть общая библиотека "testc" построение объектов класса C, реализация и A и B и затем указатели падения в обморок на их A-интерфейс:

class C: public A, public B
{
public:
  C();
  ~C();

  virtual void whatever_A();
  virtual void whatever_B();
};

A* create()
{
  return new C();
}

Наконец, у меня есть вторая общая библиотека "testd", который берет a A* как введено, и попытки бросить его к a B*, использование dynamic_cast

void process(A* a)
{
  B* b = dynamic_cast(a);
  if(b)
    b->whatever_B();
  else
    printf("Failed!\n");
}

Наконец, у меня есть главное приложение, передавая A*между библиотеками:

A* a = create();
process(a);

Вопрос

Если я создаю свое главное приложение, связываясь против 'testc' и 'testd' библиотек, все работает как ожидалось. Если, однако, я изменяю главное приложение, чтобы не связаться против 'testc' и 'testd', но вместо этого загрузить их при использовании во время выполнения dlopen/dlsym, затем dynamic_cast сбои.

Я не понимаю почему. Какие-либо подсказки?

Дополнительная информация

  • Протестированный с gcc 4.4.1, (Ubuntu 9.10) libc6 2.10.1
  • Доступный пример кода
13
задан Kees-Jan 1 January 2019 в 16:38
поделиться

3 ответа

Я нашел ответ на свой вопрос здесь . Насколько я понимаю, мне нужно сделать typeinfo доступным в testc для библиотеки testd. Для этого при использовании dlopen () необходимо сделать две дополнительные вещи:

  • При компоновке библиотеки передайте компоновщику параметр -E , чтобы убедиться, что он экспортирует все символы исполняемого файла, а не только те, которые в нем не разрешены (потому что их нет)
  • При загрузке библиотеки с помощью dlopen () добавьте параметр RTLD_GLOBAL , чтобы убедиться, что символы, экспортированные с помощью testc , также доступны для testd
15
ответ дан 1 December 2019 в 21:52
поделиться

Как правило, gcc не поддерживает RTTI через границы dlopen. У меня есть личный опыт с этой беспорядочной попыткой / уловом, но ваша проблема выглядит примерно так же. К сожалению, я боюсь, что вам придется придерживаться простых вещей в dlopen.

5
ответ дан 1 December 2019 в 21:52
поделиться

Я должен добавить к этому вопросу, так как я тоже столкнулся с этой проблемой.

Даже при предоставлении -W1, -E и использовании RTLD_GLOBAL динамические передачи по-прежнему не выполнялись. Однако передача -W1, -E также и в фактическом связывании приложения, а не только в библиотеке, похоже, исправила его.

3
ответ дан 1 December 2019 в 21:52
поделиться
Другие вопросы по тегам:

Похожие вопросы: