Sistema Linux Dlopen en C

Sistema Linux Dlopen En C



La función de biblioteca dlopen() es una función muy útil en el lenguaje C. La función carga la biblioteca en la memoria después de abrir una nueva. Generalmente lo usamos para cargar los símbolos de la biblioteca que son desconocidos en el momento de la compilación. Dlopen() es una función que se utiliza en nuestros programas. La biblioteca DL implementa dlopen(), definida en Dlfcn.h. Se requieren dos parámetros para la función dlopen: el nombre del archivo de biblioteca y la bandera. El nombre del archivo es una biblioteca dinámica y define si las dependencias de la biblioteca se calculan o no de inmediato. El dlopen() devuelve un 'controlador' que debe considerarse como un valor opaco y otras operaciones de la biblioteca DL lo utilizan. Si el intento de carga no tiene éxito, dlopen() devuelve NULL. Pero dlopen() devuelve el mismo identificador de archivo si carga la misma biblioteca muchas veces.

Mientras utiliza la función dlopen, el compilador no examina posibles errores ya que desconoce los tipos y prototipos que estamos usando. El despliegue de la función dlopen para la carga estándar no parece promoverse, excepto en algunas situaciones menores. Por cierto, es un enfoque para mejorar la introspección. Cuando el módulo compartido está siendo utilizado actualmente por otro programa, la optimización del diseño de la memoria no está particularmente interesada en la carga condicional. El consumo de memoria no aumenta cuando se carga una biblioteca utilizada anteriormente. Evitar la supervisión del compilador es peligroso y contribuye a la buena escritura de errores. Además, carecemos de la posible optimización del compilador.

Ejemplo 1:

Ahora, considere el siguiente ejemplo para ver la funcionalidad de la función dlopen en el lenguaje C. En el primer paso, cargamos algunas bibliotecas estándar de C. Aquí, cargamos la nueva biblioteca 'dlfcn.h' que se usa para definir las macros mientras se construye el argumento del modo dlopen.







Luego, introducimos otra biblioteca dentro de nuestro programa “gnu/lib-name.h”. Los archivos de la biblioteca compartida incluidos con GNU libc son encontrados por los programas de usuario de acuerdo con las macros que define. La biblioteca GNU C ofrece las bibliotecas fundamentales para los sistemas operativos GNU y GNU/Linux, así como una amplia gama de otros sistemas basados ​​en Linux. Después de eso, tenemos la implementación del método principal. Dentro de eso, declaramos el objeto puntero 'manejador' con la palabra clave void. Declaramos una función puntero seno que tiene el tipo de datos doble. Hay otra declaración del objeto puntero 'error' para el manejo de errores.



Después de eso, invocamos la función dlopen dentro del objeto 'mango'. El dlopen toma dos argumentos: LIBM_SO y 'RTLD_LAZY'. Aquí, 'LIBM_SO' es el nombre del archivo de biblioteca que proporciona funciones matemáticas como funciones trigonométricas. Esta biblioteca compartida es necesaria ya que usamos la función seno. El 'RTLD_LAZY' es otro argumento que llama a la función dlopen. Cuando se hace referencia a un símbolo determinado por primera vez, las reubicaciones deben realizarse en un momento determinado por la implementación.



Dado que es posible que un proceso no haga referencia a todos los símbolos en un archivo de objeto ejecutable, especificar RTLD LAZY debería mejorar el rendimiento en las implementaciones que permiten el enlace dinámico de símbolos. A continuación, tenemos una condición if-else para el manejo de errores cuando el objeto handle no puede realizar la función dlopen. Llamamos al dlerror para borrar el error.





La función dlerror() proporciona una cadena terminada en nulo que es legible por humanos y especifica el informe del error reciente causado por una llamada a una de las llamadas API dlopen desde la última llamada dlerror. Luego, lanzamos la función así: “(*void**)(&sine)= dlsym(handle, sin)”. Como esto es extraño, la conversión cumple con ISO C, lo que evita las advertencias del compilador. Empleamos la función dlsym que obtiene la ruta de un símbolo que se especifica dentro de un módulo de enlace dinámico al que se puede acceder a través de una función dlopen().

Además, realizamos la operación if-else nuevamente para el error estándar que se genera cuando dlerror() no es NULL. Luego, tenemos una instrucción printf donde especificamos el valor del seno que se calculará. En el último paso, cerramos ese objeto compartido invocando dlclose para el identificador devuelto por dlopen().



#incluir
#incluir
#incluye
#include

En t
principal ( En t argc , carbonizarse ** argv )
{
    vacío * resolver ;
    doble ( * suyo ) ( doble ) ;
    carbonizarse * error ;

resolver = hundir ( LIBM_SO , RTLD_LAZY ) ;
    si ( ! resolver ) {
        fprintf ( estándar , '%s \norte ' , error ( ) ) ;
        salida ( EXIT_FAILURE ) ;
    }
error ( ) ;  

    * ( vacío ** ) ( & suyo ) = dlsim ( resolver , 'sin' ) ;

    si ( ( error = error ( ) ) != NULO )   {
        fprintf ( estándar , '%s \norte ' , error ) ;
        salida ( EXIT_FAILURE ) ;
    }

    imprimir ( '%F \norte ' , ( * suyo ) ( 4.0 ) ) ;
cerrar ( resolver ) ;
    salida ( SALIR_ÉXITO ) ;
}

Usamos la opción -ldl con el comando de compilación C ya que esta es la biblioteca para la interfaz vinculada dlopen y es necesaria. Cuando se realiza la ejecución del archivo dlopen, muestra el valor del seno del valor dado anteriormente.

Ejemplo 2:

Ahora, tomamos otro ejemplo del uso de la función dlopen. Cargamos nuestro programa con todas las bibliotecas C requeridas para la implementación del código dlopen. Luego, comenzamos nuestro programa dentro del método principal. Aquí, definimos la cadena con la declaración de la variable 'src'. Luego declaramos las variables de puntero 'strlen', 'handle' y 'error'.

A continuación, llamamos a la variable handle y desplegamos la función dlopen. La función dlopen ingresa la biblioteca compartida 'libstr.so' para funciones de manejo de cadenas y el indicador 'RTLD_LAZY' que ya se demostró en el ejemplo anterior. Invocamos la función dlerror dentro de la variable “error” para borrar el error generado por la función dlopen. El if-else se utiliza para examinar los errores.

Luego, obtenemos la dirección de la función strlen usando la función dlsym y verificamos los errores mientras hacemos esto. Después de esto, usamos la función printf para llamar a la función strnlen para devolver la longitud de la cadena dada. Al final, cerramos la biblioteca compartida con la función dlclose.

#incluir
#incluir
#incluye
#include
En t principal ( vacío )
{
  carbonizarse * origen = 'Hola Linux' ;
  En t ( * estrellándose ) ( constante carbonizarse * ) ;
  vacío * resolver ;
  carbonizarse * error ;
   

resolver = hundir ( './libstr.so' , RTLD_LAZY ) ;
error = error ( ) ;
  si ( ! resolver || error != NULO ) { imprimir ( '¡Error en el intento de carga de la biblioteca! \norte %s \norte ' , error ) ;
  devolver - 1 ; }
   
  estrellándose = dlsim ( resolver , 'estrés' ) ;
error = error ( ) ;
  si ( ! estrellándose || error == NULO ) { imprimir ( '%s \norte ' , error ) ; devolver - 1 ; }

  imprimir ( 'La Longitud de la Cadena es:%d \norte ' , estrellándose ( origen ) ) ;
cerrar ( resolver ) ;
  devolver 0 ;
}

Usamos el siguiente comando para la ejecución del programa dado. Aquí, el indicador -lstr se usa para la función de longitud de cadena y el ldl se usa para el archivo de biblioteca dlopen. El programa compilado da la longitud de la cadena como se muestra en el shell:

Conclusión

La información se proporciona con respecto a la función dlopen del lenguaje C en este artículo. Tenemos una breve introducción de la función dlopen. Luego, implementamos dos ejemplos. La función devuelve un identificador que define la biblioteca abierta. Las direcciones de las funciones dentro de la biblioteca abierta se determinan luego utilizando este identificador y la función dlsym. La dirección de una función dentro de una biblioteca que ya se ha abierto usando dlopen se puede encontrar usando la función dlsym.