El enlazador dinámico en realidad busca en varios lugares para encontrar cada biblioteca dinámica. Estos incluyen (de man ld.so):
- Rutas dadas por la variable de entorno
LD_LIBRARY_PATH
- Las rutas integradas en el binario cargan la biblioteca bajo el
DT_RUNPATH
entrada - El archivo de caché /etc/ld.so.cache
- /lib y /usr/lib
Si desea obtener la ruta de una biblioteca compartida específica, recomendaría el dladdr
función. Desde la página del manual:
La función dladdr() toma un puntero de función e intenta resolver el nombre y el archivo donde se encuentra. La información se almacena en el Dl_info
estructura:
typedef struct {
const char *dli_fname; /* Pathname of shared object that
contains address */
void *dli_fbase; /* Address at which shared object
is loaded */
const char *dli_sname; /* Name of nearest symbol with address
lower than addr */
void *dli_saddr; /* Exact address of symbol named
in dli_sname */
} Dl_info;
Si no se pudo encontrar ningún símbolo que coincida con la dirección, entonces dli_sname
y dli_saddr
están establecidos en NULL
.
dladdr()
devuelve 0 en caso de error y distinto de cero en caso de éxito.
Así que solo le da un puntero de función, y le dará el nombre del archivo que lo proporciona y un montón de otra información. Entonces, por ejemplo, podría hacer que un constructor en una biblioteca llame a esto para averiguar la ruta completa de la biblioteca:
#define _GNU_SOURCE
#include <dlfcn.h>
#include <stdio.h>
__attribute__((constructor))
void on_load(void) {
Dl_info dl_info;
dladdr((void *)on_load, &dl_info);
fprintf(stderr, "module %s loaded\n", dl_info.dli_fname);
}
Esta función también funciona en OS X con la misma semántica.