Trabajar con bibliotecas compartidas | conjunto 2

Hemos cubierto información básica sobre bibliotecas compartidas en la publicación anterior . En el artículo actual, aprenderemos cómo crear bibliotecas compartidas en Linux. 

Antes de eso, necesitamos comprender cómo se carga un programa en la memoria y los diversos pasos (básicos) involucrados en el proceso. 

Veamos un programa típico de «Hola Mundo» en C. A continuación se muestra la imagen de pantalla del programa simple Hola Mundo. 

Hello World

Estábamos compilando nuestro código usando el comando “ gcc -o sample shared.c ” Cuando compilamos nuestro código, el compilador no resolverá la implementación de la función printf() . Sólo verifica la comprobación sintáctica. La string de herramientas deja un resguardo en nuestra aplicación que será llenado por un enlazador dinámico. Dado que printf es una función estándar, el compilador invoca implícitamente su biblioteca compartida. Más detalles abajo. 

Estamos usando I dd para enumerar las dependencias de la imagen binaria de nuestro programa. En la imagen de la pantalla, podemos ver que nuestro programa de muestra depende de tres archivos binarios, a saber, linux-vdso.so.1 , libc.so.6 y /lib64/ld-linux-x86-64.so.2

El archivo VDSO es una implementación rápida de la interfaz de llamada del sistema y algunas otras cosas, no es nuestro enfoque (en algunos sistemas más antiguos, puede ver el nombre de archivo diferente en una línea de *.vsdo.*). Ignora este archivo. Tenemos interés en los otros dos archivos. 

El archivo libc.so.6 es la implementación en C de varias funciones estándar. Es el archivo donde vemos la definición de printf necesaria para nuestro Hello World . Es la biblioteca compartida que se necesita cargar en la memoria para ejecutar nuestro programa Hello World. 

El tercer archivo /lib64/ld-linux-x86-64.so.2 es, de hecho, un ejecutable que se ejecuta cuando se invoca una aplicación. Cuando invocamos el programa en el terminal bash, típicamente el bash se bifurca y reemplaza su espacio de direcciones con una imagen del programa a ejecutar (el llamado par fork-exec). El kernel verifica si libc.so.6 reside en la memoria. Si no, cargará el archivo en la memoria y reubicará los símbolos libc.so.6. Luego invoca el enlazador dinámico (/lib64/ld-linux-x86-64.so.2) para resolver los símbolos no resueltos del código de la aplicación (printf en el presente caso). Luego, el control se transfiere a nuestro programa principal . (He omitido intencionalmente muchos detalles en el proceso, nuestro enfoque es comprender los detalles básicos). 

Creando nuestra propia biblioteca compartida: 

Trabajemos con una biblioteca compartida simple en Linux. Cree un archivo library.c con el siguiente contenido. 

library

El archivo library.c define una función signum que será utilizada por nuestro código de aplicación. Compile el archivo library.c usando el siguiente comando. 

gcc -shared -fPIC -o liblibrary.so biblioteca.c 

El flag-shared le indica al compilador que estamos construyendo una biblioteca compartida. El indicador -fPIC es para generar código independiente de la posición (ignorar por ahora). El comando genera una biblioteca compartida liblibrary.so en el directorio de trabajo actual. Tenemos nuestro archivo de objeto compartido (nombre de la biblioteca compartida en Linux) listo para usar. 

Cree otro archivo application.c con el siguiente contenido. 

application

En el archivo application.c estamos invocando la función signum que se definió en una biblioteca compartida. Compile el archivo application.c usando el siguiente comando. 

aplicación gcc.c -L /home/geetanjali/codificación/ -biblioteca -o muestra 

La biblioteca de banderas indica al compilador que busque definiciones de símbolos que no están disponibles en el código actual (función signum en nuestro caso). La opción -L es una sugerencia para que el compilador busque en el directorio seguido de la opción para cualquier biblioteca compartida (solo durante el tiempo de enlace). El comando genera un ejecutable llamado » muestra «. 

Si invoca el ejecutable, el enlazador dinámico no podrá encontrar la biblioteca compartida requerida. De forma predeterminada, no buscará en el directorio de trabajo actual. Debe indicar explícitamente a la string de herramientas que proporcione las rutas adecuadas. El enlazador dinámico busca rutas estándar disponibles en LD_LIBRARY_PATH y también busca en la memoria caché del sistema (para obtener detalles, explore el comando ldconfig ). Tenemos que agregar nuestro directorio de trabajo a la variable de entorno LD_LIBRARY_PATH. El siguiente comando hace lo mismo. 

exportar LD_LIBRARY_PATH=/home/geetanjali/codificación/:$LD_LIBRARY_PATH 

Ahora puede invocar nuestro ejecutable como se muestra. 

./muestra 

La salida de muestra en mi sistema se muestra a continuación. 

output

Nota: La ruta  /home/geetanjali/coding/ es una ruta de directorio de trabajo en mi máquina. Debe usar la ruta del directorio de trabajo donde sea que se use en los comandos anteriores. 

Estén atentos, ni siquiera hemos explorado 1/3 de los conceptos de biblioteca compartida. Conceptos más avanzados en los artículos posteriores. 

Ejercicio: 

Es un libro de trabajo como un artículo. No ganarás mucho a menos que practiques e investigues un poco. 

1. Cree un ejemplo similar y escriba su propia función en la biblioteca compartida. Invoque la función en otra aplicación. 

2. ¿Existe(n) alguna otra herramienta(s) que pueda enumerar las bibliotecas dependientes? 

3. ¿Qué es el código independiente de posición (PIC)? 

4. ¿Qué es la memoria caché del sistema en el contexto actual? ¿Cómo se relaciona el directorio /etc/ld.so.conf.d/* en el contexto actual? 

—  Venki . Escriba comentarios si encuentra algo incorrecto o si desea compartir más información sobre el tema tratado anteriormente.
 

Publicación traducida automáticamente

Artículo escrito por GeeksforGeeks-1 y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *