2009-01-26 22 views
18

Estoy escribiendo un código que usa bibliotecas dinámicas compartidas como complementos.Recibo un error de "símbolo no definido" al cargar la biblioteca con dlopen

Mi línea de comandos para la construcción de las bibliotecas compartidas se parece a:

cc -shared -fPIC -o module.so -g -Wall module.c 

Dentro del módulo, puedo llamar a las funciones que se encuentran en cualquier otra biblioteca compartida que se ha cargado en el ejecutable principal.

Sin embargo, no puedo acceder a las funciones (que se exportan) que se encuentran en el archivo ejecutable (obtengo errores de undefined symbol).

Mi llamado a dlopen se parece a esto:

void *handle = dlopen(plugin, RTLD_NOW); 

Puede alguien aconsejar por favor cómo mi módulo puede llamar de nuevo a mi ejecutable, sin tener que poner todas las funciones de utilidad de los ejecutables en otra biblioteca compartida?

Respuesta

5

He encontrado la respuesta yo mismo.

Tuve que agregar los indicadores --export-dynamic a las opciones de enlace para el ejecutable principal.

Al crear un enlazada dinámicamente ejecutable, poner todos los símbolos de la tabla de símbolos dinámico . La tabla de símbolos dinámica es el conjunto de símbolos que son visibles desde los objetos dinámicos en tiempo de ejecución.

Si no utiliza esta opción, la tabla símbolo dinámico normalmente contener sólo aquellos símbolos que son referenciado por un objeto dinámico mencionado en el enlace.

Si utiliza "dlopen" para cargar un objeto dinámico que debe referirse de nuevo a los símbolos definidos por el programa, lugar de algún otro objeto dinámico, entonces es probable que tenga que utilizar esta opción cuando enlazando el programa .

29

La solución correcta es agregar -rdynamic al comando de enlace del ejecutable principal. Esto agregará la opción apropiada al ld (que, al usar GNU ld, pasa a ser --export-dynamic).

Agregar --export-dynamic directamente es técnicamente incorrecto: es una opción del vinculador, por lo que debe agregarse como -Wl,--export-dynamic o -Wl,-E. Esto también es menos portátil que -rdynamic (otros vinculadores tienen un equivalente, pero la opción en sí es diferente).

+0

Esta solución también se aplica cuando se utilizan las extensiones de Boost, ya que la clase de boost shared_library está utilizando dlopen (en Linux) para cargar la biblioteca. –

4

Cuando me encontré con el mismo problema, acabo de utilizar la siguiente solución. Antes de cargar ningún plugin, sólo tiene que cargar el programa en sí, con lo que sus símbolos para tablas dinámicas:

dlopen(NULL,RTLD_NOW|RTLD_GLOBAL); 

Creo que la solución es mejor.El motivo es que también resuelve el mismo problema si

a) su programa (o un módulo de terceros) está vinculado (no en tiempo de ejecución) con la biblioteca compartida, cuyos símbolos deben estar en la tabla dinámica;

b) no se puede recompilar ese módulo con el distintivo -dinámico.

Cuestiones relacionadas