2012-07-30 10 views
6

Estoy intentando crear una biblioteca compartida utilizando gcc 4.6 en Linux, que se carga dinámicamente. Como se describe en muchos artículos en la web, así como en preguntas anteriores, proporciono métodos de fábrica estilo c en la biblioteca para crear y destruir objetos. El código - en forma mínima - se parece a esto:Símbolo no definido "typeinfo" con la biblioteca cargada dinámicamente

base.h:

class base { 
public: 
    base(); 
    virtual ~base(); 
    virtual int value() = 0; 
}; 

base.cpp:

#include "base.h" 
base::base() {} 
base::~base() {} 

main.cpp:

#include "base.h" 
#include <dlfcn.h> 
#include <iostream> 

int main() { 
    void* handle = dlopen("liblib.so", RTLD_NOW); 
    if(handle == NULL) std::cout << dlerror() << std::endl; 

    // dlsym, ... 
} 

lib. cpp:

class derived : public base { 
public: 
    derived() {} 
    virtual ~derived() {} 
    virtual int value() { return 42; } 
}; 

extern "C" derived* create_object() { 
    return new derived(); 
} 

Se compila bien con:

g++ -shared -fPIC lib.cpp -o liblib.so 
g++ base.cpp main.cpp -ldl -o app 

En tiempo de ejecución, sin embargo se bloquea debido a una falta typeinfo símbolo

liblib.so: undefined symbol: _ZTI4base 

En las preguntas anteriores que encontré aquí, este error fue por lo general ya sea debido a alguna falta "= 0" o una definición faltante de una función virtual. Sin embargo, en el ejemplo anterior, base :: value es puramente virtual y el destructor tiene una definición. Por extraño que parezca nm informa _ZTI4base como definied de aplicación:

$ nm app | grep _ZTI4base 
0000000000601050 V _ZTI4base 

Entonces ¿por qué no es el enlazador Usando esta definición?

La única forma que encontré hasta ahora para hacer que el código funcione es implementar constructur y destructor en el archivo de encabezado. Sin embargo, después de hacer esto, los símbolos correspondientes para base se informan en liblib.so por nm y desaparecen totalmente de la aplicación, lo que probablemente significa que sus definiciones se compilaron en la biblioteca y no en la aplicación, que no es lo que quería lograr. ¿Alguien tiene una idea de cómo hacer que lo anterior funcione sin hacer esto?

+1

Proporcione '--demangle' a' nm' para ver el nombre solicitado de la función. – Shahbaz

Respuesta

2

Necesita la opción -rdynamic al vincular el programa, exportar sus símbolos y ponerlos a disposición de las bibliotecas cargadas con dlopen().

Cuestiones relacionadas