dynamic_cast falha quando usado com dlopen / dlsym

Introdução

Deixe-me pedir desculpas antecipadamente pela longa pergunta. É o mais curto que pude, o que, infelizmente, não é muito curto.

Configuração

Eu defini duas interfaces, A e 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;
};

Então, eu tenho uma biblioteca compartilhada "testc" construindo objetos da classe C, implementando A e B e passando ponteiros para a interface A:

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

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

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

Por fim, tenho uma segunda biblioteca compartilhada "testd", que leva umA* como entrada e tenta convertê-lo em umB*, usandodynamic_cast

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

Finalmente, tenho a aplicação principal, passandoA*entre as bibliotecas:

A* a = create();
process(a);
Pergunta, questão

Se eu construir meu aplicativo principal, vinculando-se às bibliotecas 'testc' e 'testd', tudo funcionará conforme o esperado. No entanto, se eu modificar o aplicativo principal para não vincular 'testc' e 'testd', mas carregá-los em tempo de execução usandodlopen/dlsym, então odynamic_cast falha.

Eu não entendo o porquê. Alguma pista?

Informação adicionalTestado com gcc 4.4.1, libc6 2.10.1 (Ubuntu 9.10)Código de exemplo acessível

questionAnswers(4)

yourAnswerToTheQuestion