Estoy usando ciertas herramientas GNU, es decir, el Compilador GNU C++ (g ++) y el Enlazador GNU (ld) para crear una biblioteca compartida (.so) así como un archivo binario ejecutable.Problema al obtener el enlazador GNU (ld) para exportar un símbolo
El archivo ejecutable binario utiliza la función dlopen
para cargar dinámicamente el archivo de biblioteca compartida en tiempo de ejecución. Además de esto, el archivo de biblioteca compartida necesita invocar un método de clase particular (llamado ToolboxManager::registerToolbox
) que se define dentro del ejecutable binario. Esto se soluciona obligando al ejecutable binario a exportar el método de clase, que a su vez se lleva a cabo en tiempo de enlace al vincular el ejecutable binario con las siguientes opciones de línea de comando;
-Wl,--dynamic-list=${top_srcdir}/dynamic_symbol_table.txt
donde el archivo ${top_srcdir}/dynamic_symbol_table.txt
contiene el siguiente contenido;
{
extern "C++"
{
"ToolboxManager::registerToolbox*";
};
};
Nota el uso del asterisco (*) en el archivo para forzar al enlazador a exportar todos los símbolos que comienzan con ToolboxManager::registerToolbox
.
Cuando ejecuto la utilidad GNU nm (nm -C -g ./a.out
) en el ejecutable binario resultante, muestra la siguiente información sobre el método de clase mencionado anteriormente;
08053da0 T ToolboxManager::registerToolbox
(
std::string&,
std::string&,
std::map
<
std::string,
Factory_DSPB_Base*,
std::less
<
std::string
>,
std::allocator
<
std::pair
<
std::string const,
Factory_DSPB_Base*
>
>
>&
)
o, si la utilidad nm se invoca que el anterior, pero esta vez sin el uso de la opción de línea de comandos -C;
08053da0 T _ZN14ToolboxManager15registerToolboxERSsS0_RSt3mapISsP17Factory_DSPB_BaseSt4lessISsESaISt4pairIKSsS3_EEE
Hasta ahora, esto se ve bien. La "T" delante de la definición del método de clase ToolboxManager::registerToolbox
, denota que el método reside dentro de la sección Texto/Código del archivo.
De forma similar, si ejecuto la utilidad nm (nm -C -g ./toolbox.so
) en el archivo de biblioteca compartida, muestra la siguiente información sobre el mismo método de clase ;
U ToolboxManager::registerToolbox
(
std::string&,
std::string&,
std::map
<
std::string,
Factory_DSPB_Base*,
std::less
<
std::string
>,
std::allocator
<
std::pair
<
std::string const,
Factory_DSPB_Base*
>
>
>&
)
Esto también se ve bien. La "U" en frente de la definición del método de clase ToolboxManager::registerToolbox
, denota que el método no está definido en el archivo de biblioteca compartida.
Sin embargo, ocurre un problema cuando ejecuto el binario exextible desde la línea de comandos y este problema da como resultado el siguiente mensaje de error;
./toolbox.so: undefined symbol: _ZN14ToolboxManager15registerToolboxERSsS0_RSt3mapISsP17Factory_DSPB_BaseSt4lessISsESaISt4pairIKSsS3_EEE
La clase nombre del método mangled que aparece en este mensaje de tiempo de ejecución se muestra a continuación, como la primera de las dos líneas. Para fines de comparación, el nombre del método de clase alterado de arriba (y que se generó utilizando el comando nm -g
) se muestra a continuación como la segunda de las dos líneas;
_ZN14ToolboxManager15registerToolboxERSsS0_RSt3mapISsP17Factory_DSPB_BaseSt4lessISsESaISt4pairIKSsS3_EEE
_ZN14ToolboxManager15registerToolboxERSsS0_RSt3mapISsP17Factory_DSPB_BaseSt4lessISsESaISt4pairIKSsS3_EEE
Como puede verse, los dos nombres alterados son idénticos. Por lo tanto, no puedo entender por qué el símbolo indefinido no puede resolverse en tiempo de ejecución.
Luego volví a vincular el ejecutable binario, sin embargo esta vez reemplacé el siguiente comando del enlazador;
-Wl,--dynamic-list=${top_srcdir}/dynamic_symbol_table.txt
con el este;
-Wl,--export-dynamic
La opción del vinculador --export-dynamic
instruye al enlazador GNU para agregar todos los símbolos de la tabla de símbolos dinámicos.
Si luego ejecutó el ejecutable binario nuevamente. Esta vez ejecutó correctamente el y la llamada a la función dlopen no produjo un error de símbolo indefinido. Esto me tiene completamente perplejo, ya que parece que el símbolo se está exportando correctamente en la versión inicial del ejecutable binario. ¿Alguien puede ver el problema aquí? Cualquier ayuda sería inmensamente apreciada.
Gracias de antemano.