table of contents
DLOPEN(3) | Manual del Programador de Linux | DLOPEN(3) |
NOMBRE¶
dlclose, dlerror, dlopen, dlsym - Interfaz de programación con el cargador de enlace dinámicoSINOPSIS¶
#include <dlfcn.h> void *dlopen(const char *filename, int flag);DESCRIPCIÓN¶
dlopen carga una biblioteca dinámica del fichero dado por la cadena terminada en null filename y devuelve un "manejador" (handle) opaco para la biblioteca dinámica. Si filename no es una ruta absoluta (es decir, no comienza por "/"), se busca el fichero en las siguientes localizaciones:
Una lista de directorios separados por puntos en la variable de entorno
LD_LIBRARY_PATH del usuario.
La lista de bibliotecas puestas en caché en /etc/ld.so.cache.
/lib, seguido de /usr/lib.
Si filename es un puntero NULL, el manejador devuelto es para el programa
principal.
Las referencias externas en la biblioteca se resuelven usando las bibliotecas en
esa lista de dependencias de bibliotecas y en cualquier otra biblioteca
previamente abierta con la opción RTLD_GLOBAL. Si el ejecutable
fue enlazado con la opción "-rdynamic", los símbolos
globales del ejecutable también se utilizarán para resolver
referencias en una biblioteca cargada dinámicamente.
flag debe ser o bien RTLD_LAZY, lo que significa que los
símbolos no definidos se resolverán cuando se ejecute el
código de la biblioteca dinámica, o RTLD_NOW, lo que
significa que se deben resolver todos los símbolos no definidos antes
de que dlopen regrese, y falla si esto no puede hacerse. Opcionalmente,
RTLD_GLOBAL puede añadirse a flag, mediante una
operación OR, en cuyo caso los símbolos externos definidos en la
biblioteca se hacen disponibles para las bibliotecas cargadas posteriormente.
Si la biblioteca exporta una rutina llamada _init, ese código se
ejecuta antes de que dlopen regrese. Si la misma biblioteca se carga dos veces
con dlopen(), se devuelve el mismo manejador. La biblioteca dl mantiene
contadores de referencias para los manejadores de ficheros dinámicos,
por lo que una biblioteca dinámica no se descargará hasta que
dlclose no se haya invocado sobre ella tantas veces como dlopen
se haya ejecutado con éxito sobre la misma.
Si dlopen falla por alguna razón se devuelve NULL. Se puede
extraer una cadena que describa el error más reciente que
ocurrió en cualquiera de las rutinas dl (dlopen, dlsyn o dlclose) en un
formato entendible por el usuario con la función dlerror().
dlerror devuelve NULL si no ha ocurrido ningún error desde la
inicialización o desde que fue llamada por última vez. (Llamar a
dlerror() dos veces consecutivas, siempre provocará que la
segunda llamada devuelva NULL.)
dlsym toma el manejador de una biblioteca dinámica devuelto por
dlopen y el nombre del símbolo terminado en null y devuelve la
dirección donde se ha cargado ese símbolo. Si el símbolo
no se encontró, dlsym devuelve NULL; sin embargo, la manera
correcta de comprobar un error de dlsym es guardar el resultado de
dlerror en una variable y comprobar si el valor guardado es distinto de
NULL. Esto es así porque el valor del símbolo podría ser
realmente NULL. También es necesario guardar los resultados de
dlerror en una variable, porque si se llama otra vez a dlerror
devolverá NULL.
Hay dos pseudo-manejadores especiales, RTLD_DEFAULT y RTLD_NEXT.
El primero buscará la primera ocurrencia del símbolo deseado
usando el orden de búsqueda de bibliotecas por defecto. El segundo, que
sólo se puede usar desde dentro de una biblioteca dinámica,
buscará la siguiente ocurrencia de una función en el orden de
búsqueda tras la biblioteca actual. Esto nos permite proporcionar un
"envoltorio" ( wrapper) alrededor de una función en
otra biblioteca compartida.
dlclose decrementa la cuenta de referencias sobre el manejador de
biblioteca dinámica handle. Si la cuenta de referencias llega a
cero y ninguna biblioteca cargada usa los símbolos en ella, la
biblioteca dinámica se descarga. Si la biblioteca dinámica
exporta una rutina llamada _fini, esa rutina es llamada justo antes de
que la biblioteca sea descargada.
VALOR DEVUELTO¶
dlclose devuelve 0 en caso de éxito y un valor distinto de cero en caso de error.EJEMPLO¶
Carga la biblioteca matemática e imprime el coseno de 2.0:#include <stdio.h> #include <dlfcn.h> int main(int argc, char **argv) { void *handle; double (*cosine)(double); char *error; handle = dlopen ("libm.so", RTLD_LAZY); if (!handle) { fprintf (stderr, "%s\n", dlerror()); exit(1); } cosine = dlsym(handle, "cos"); if ((error = dlerror()) != NULL) { fprintf (stderr, "%s\n", error); exit(1); } printf ("%f\n", (*cosine)(2.0)); dlclose(handle); return 0; }
gcc -rdynamic -o foo foo.c -ldl
OBSERVACIONES¶
Los símbolos RTLD_DEFAULT y RTLD_NEXT están definidos por <dlfcn.h> sólo cuando se definió _GNU_SOURCE antes de incluir dicho fichero cabecera.HISTORIA¶
La interfaz estándar dlopen viene de SunOS.VÉASE TAMBIÉN¶
ld(1), ld.so(8), ldconfig(8), ldd(1), ld.so.info14 diciembre 2001 | Linux |