Позвольте мне принести извинения заранее за долгий вопрос. Это столь коротко, как я мог сделать его, который, к сожалению, не очень короток.
Я определил два интерфейса, 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
сбои.
Я не понимаю почему. Какие-либо подсказки?
Я нашел ответ на свой вопрос здесь . Насколько я понимаю, мне нужно сделать typeinfo доступным в testc для библиотеки testd. Для этого при использовании dlopen ()
необходимо сделать две дополнительные вещи:
-E
, чтобы убедиться, что он экспортирует все символы исполняемого файла, а не только те, которые в нем не разрешены (потому что их нет) dlopen ()
добавьте параметр RTLD_GLOBAL
, чтобы убедиться, что символы, экспортированные с помощью testc
, также доступны для testd
Как правило, gcc не поддерживает RTTI через границы dlopen. У меня есть личный опыт с этой беспорядочной попыткой / уловом, но ваша проблема выглядит примерно так же. К сожалению, я боюсь, что вам придется придерживаться простых вещей в dlopen.
Я должен добавить к этому вопросу, так как я тоже столкнулся с этой проблемой.
Даже при предоставлении -W1, -E
и использовании RTLD_GLOBAL
динамические передачи по-прежнему не выполнялись. Однако передача -W1, -E
также и в фактическом связывании приложения, а не только в библиотеке, похоже, исправила его.