Roger1 libreria

25
Archivos complementarios a Archivos complementarios a aplicaciones en Win32 aplicaciones en Win32 El sistema operativo Windows esta compuesto El sistema operativo Windows esta compuesto por una extensa variedad de módulos por una extensa variedad de módulos adicionales al “kernel”, entre ellos podemos adicionales al “kernel”, entre ellos podemos encontrar: encontrar: Drivers” ( Drivers” ( . . drv drv y .sys y .sys ) ) Drivers virtuales” ( Drivers virtuales” ( . . vxd) vxd) Bibliotecas estáticas ( Bibliotecas estáticas ( . . lib) lib) Bibliotecas dinámicas ( Bibliotecas dinámicas ( . . dll) dll)

Transcript of Roger1 libreria

Page 1: Roger1 libreria

Archivos complementarios a Archivos complementarios a aplicaciones en Win32aplicaciones en Win32

El sistema operativo Windows esta compuesto El sistema operativo Windows esta compuesto por una extensa variedad de módulos por una extensa variedad de módulos adicionales al “kernel”, entre ellos podemos adicionales al “kernel”, entre ellos podemos encontrar:encontrar:

• ““Drivers” (Drivers” (..drvdrv y .sys y .sys))

• ““Drivers virtuales” (Drivers virtuales” (..vxd)vxd)

• Bibliotecas estáticas (Bibliotecas estáticas (..lib)lib)

• Bibliotecas dinámicas (Bibliotecas dinámicas (..dll)dll)

Page 2: Roger1 libreria

Bibliotecas estáticasBibliotecas estáticas

• Son aquellas que se requieren durante el Son aquellas que se requieren durante el tiempo de compilación.tiempo de compilación.

• Generalmente se tienen en un archivo con Generalmente se tienen en un archivo con extensión .lib y un archivo de encabezado extensión .lib y un archivo de encabezado con extensión .hcon extensión .h

• No se requieren en la máquina del “cliente” No se requieren en la máquina del “cliente” para ejecutar un programa, pero generan un para ejecutar un programa, pero generan un código ejecutable grande.código ejecutable grande.

Page 3: Roger1 libreria

Biblioteca estáticaBiblioteca estática

Supóngase que dentro de un programa se desea utilizar unarutina cuyo código ya fué desarrollado anteriormente, quizáspor alguien que no es el programador actual.

Para hacer esto se requiren tres cosas:• Conocer los parámetros que requiere y el tipo de dato que regresa la función (API).

• Archivo con prototipo de la función.

• Archivo con código intermedio de la función.

long Multiply2Longs(long l1, long l2);

Page 4: Roger1 libreria

Aplicación que utiliza biblioteca estáticaAplicación que utiliza biblioteca estáticaSupóngase que dentro de un programa se desea utilizar unaSupóngase que dentro de un programa se desea utilizar unarutina cuyo código ya fué desarrollado anteriormente, quizásrutina cuyo código ya fué desarrollado anteriormente, quizáspor alguien que no es el programador actual.por alguien que no es el programador actual.

#include <stdio.h>#include <stdlib.h>#include <windows.h>

long l1;long l2;long lResult;

extern "C" long Multiply2Longs(long l1, long l2);

void main() {//Inclusión explícita: Requiere la inclusión del archivo .LIB

l1=10;l2=20;

lResult=Multiply2Longs(l1,l2);printf("Resultado=%d\n",lResult);

getchar();}

Si solo es necesaria una función,se puede dejar indicada en vez derealizar el #include del archivo.

Page 5: Roger1 libreria

Aplicación que utiliza biblioteca estáticaAplicación que utiliza biblioteca estática

Page 6: Roger1 libreria

Código de la biblioteca estáticaCódigo de la biblioteca estáticaEl código de una biblioteca estática es simple, consisteEl código de una biblioteca estática es simple, consisteúnicamente de las rutinas que la componen y su códigoúnicamente de las rutinas que la componen y su códigointerno.interno.

La única consideración que cabe destacar se presenta al compilarLa única consideración que cabe destacar se presenta al compilarel archivo, esto debido a que no se generará otro archivo conel archivo, esto debido a que no se generará otro archivo conextensión .exe sino uno con extensión .lib.extensión .exe sino uno con extensión .lib.

Page 7: Roger1 libreria

Código de una biblioteca estáticaCódigo de una biblioteca estática

Al crear el proyecto, se debe especificar que se va Al crear el proyecto, se debe especificar que se va a generar el código para una biblioteca estática.a generar el código para una biblioteca estática.

Page 8: Roger1 libreria

Bibliotecas dinámicasBibliotecas dinámicas

• Archivos precomilados que pueden Archivos precomilados que pueden enlazarse al código principal durante la enlazarse al código principal durante la etapa de ejecución de una aplicación.etapa de ejecución de una aplicación.

• El archivo con extensión DLL se requiere El archivo con extensión DLL se requiere en la máquina del “cliente” para que pueda en la máquina del “cliente” para que pueda ejecutarse la aplicación.ejecutarse la aplicación.

• Normalmente, los DLLs van al directorio \Normalmente, los DLLs van al directorio \windows\system o \windows\system32windows\system o \windows\system32

Page 9: Roger1 libreria

Preparación para utilizar un DLLPreparación para utilizar un DLL

Page 10: Roger1 libreria

Aplicación que utiliza DLLAplicación que utiliza DLL

#include <stdio.h>#include <stdlib.h>#include <windows.h>

HINSTANCE hCodigoDll;

long l1;long l2;long lResult;

typedef long (TIPOFUNCION)(long, long);TIPOFUNCION* pfuncMultiply2Longs=0;

En forma similar al manejo de archivos,se define una variable que servirá paraabrir el DLL.

Page 11: Roger1 libreria

Aplicación que utiliza DLLAplicación que utiliza DLL

#include <stdio.h>#include <stdlib.h>#include <windows.h>

HINSTANCE hCodigoDll;

long l1;long l2;long lResult;

typedef long (TIPOFUNCION)(long, long);

TIPOFUNCION* pfuncMultiply2Longs=0;

Se define un tipo de dato que deberá corresponderal prototipo de la función.Se define un apuntador al tipo de función que sedefinió en el párrafo anterior.

Page 12: Roger1 libreria

Aplicación que utiliza DLLAplicación que utiliza DLLvoid main() {

//Inclusión implícita: Realiza inclusión dinámica de la bibliotecaif (hCodigoDll =LoadLibrary("dll_test.dll")) {

if (pfuncMultiply2Longs=(TIPOFUNCION*)

GetProcAddress(hCodigoDll ,"Multiply2Longs")) {

l1=10;l2=20;lResult=(*pfuncMultiply2Longs)(l1,l2);

printf("Resultado=%d\n",lResult);} else

printf("Error al obtener la dirección del procedimiento!\n");} else

printf("Biblioteca no localizada!\n");FreeLibrary(hModule);

getchar();} Se “carga” el DLL y se liga

con la variable hModule.

Page 13: Roger1 libreria

Aplicación que utiliza DLLAplicación que utiliza DLLvoid main() {

//Inclusión implícita: Realiza inclusión dinámica de la bibliotecaif (hCodigoDll =LoadLibrary("dll_test.dll")) {

if (pfuncMultiply2Longs=(TIPOFUNCION*)

GetProcAddress(hCodigoDll ,"Multiply2Longs")) {

l1=10;l2=20;lResult=(*pfuncMultiply2Longs)(l1,l2);

printf("Resultado=%d\n",lResult);} else

printf("Error al obtener la dirección del procedimiento!\n");} else

printf("Biblioteca no localizada!\n");FreeLibrary(hModule);

getchar();}

Se busca dentro del DLL la funciónque nos interesa invocar, utilizandopara ello la referencia hModule.

Page 14: Roger1 libreria

Aplicación que utiliza DLLAplicación que utiliza DLLvoid main() {

//Inclusión implícita: Realiza inclusión dinámica de la bibliotecaif (hCodigoDll =LoadLibrary("dll_test.dll")) {

if (pfuncMultiply2Longs=(TIPOFUNCION*)

GetProcAddress(hCodigoDll,"Multiply2Longs")) {

l1=10;l2=20;lResult=(*pfuncMultiply2Longs)(l1,l2);

printf("Resultado=%d\n",lResult);} else

printf("Error al obtener la dirección del procedimiento!\n");} else

printf("Biblioteca no localizada!\n");FreeLibrary(hModule);

getchar();} Si la función fué localizada, se liga

con el apuntador pfuncMultiply2Longs.

Page 15: Roger1 libreria

Aplicación que utiliza DLLAplicación que utiliza DLLvoid main() {

//Inclusión implícita: Realiza inclusión dinámica de la bibliotecaif (hCodigoDll =LoadLibrary("dll_test.dll")) {

if (pfuncMultiply2Longs=(TIPOFUNCION*)

GetProcAddress(hCodigoDll ,"Multiply2Longs")) {

l1=10;l2=20;lResult=(*pfuncMultiply2Longs)(l1,l2);

printf("Resultado=%d\n",lResult);} else

printf("Error al obtener la dirección del procedimiento!\n");} else

printf("Biblioteca no localizada!\n");FreeLibrary(hCodigoDll);

getchar();}

Se manda ejecutar el contenido del apuntadorpfuncMultiply2Longs, en forma similar acomo se invoca una función.

Page 16: Roger1 libreria

Código de unCódigo de un DLL DLL

//Archivo dll_test.c

#include <windows.h>

#define DllExport __declspec(dllexport)

DllExport long Multiply2Longs(long n1, long n2) {return(n1*n2);

}

Page 17: Roger1 libreria

Bibliotecas en LINUXBibliotecas en LINUX

• Existen tres tipos de bibliotecas.Existen tres tipos de bibliotecas.– De enlace De enlace estáticoestático..– De enlace De enlace dinámicodinámico (“shared object”). (“shared object”).

• Con enlace Con enlace implícitoimplícito: Etiquetadas durante tiempo de : Etiquetadas durante tiempo de compilación con rutinas implícitamente enlazadas durante compilación con rutinas implícitamente enlazadas durante tiempo de ejecución.tiempo de ejecución.

• Con enlace Con enlace explícitoexplícito: Explícitas en el procedimiento de enlace : Explícitas en el procedimiento de enlace y desenlace durante tiempo de ejecución.y desenlace durante tiempo de ejecución.

• Para soportar el proceso de enlace dinámico el Para soportar el proceso de enlace dinámico el sistema operativo utiliza un módulo de código sistema operativo utiliza un módulo de código llamado “dynamic linker”.llamado “dynamic linker”.

Page 18: Roger1 libreria

Formatos de código binarioFormatos de código binario• Todos los tipos de bibliotecas consisten de código binario que debe ser Todos los tipos de bibliotecas consisten de código binario que debe ser

enlazado al código binario de un programa para su ejecución.enlazado al código binario de un programa para su ejecución.

• El vinculador (“linker”) debe realizar un proceso de relocalización de El vinculador (“linker”) debe realizar un proceso de relocalización de códigocódigo cada vez que una biblioteca se enlaza con una aplicación. cada vez que una biblioteca se enlaza con una aplicación.

• Para que en vinculador (dinámico o estático, cualquiera de ellos) Para que en vinculador (dinámico o estático, cualquiera de ellos) pueda realizar su función requiere un formato estandarizado de pueda realizar su función requiere un formato estandarizado de código; en Linux existen dos:código; en Linux existen dos:– COFFCOFF (“Common Object File Format”): Utilizado inicialmente pero (“Common Object File Format”): Utilizado inicialmente pero

descontinuado en la actualidad.descontinuado en la actualidad.– ELFELF (“Executable Linkage Format”): Vigente en todas las distribuciones (“Executable Linkage Format”): Vigente en todas las distribuciones

del sistema operativo.del sistema operativo.

Page 19: Roger1 libreria

Tablas de símbolosTablas de símbolos• Una vez que se realiza el proceso de Una vez que se realiza el proceso de compilación del código fuentecompilación del código fuente, ,

se se pierdenpierden todas las todas las referencias a los nombres referencias a los nombres de variables y rutinas, de variables y rutinas, en el código objeto solo quedan referencias a memoria dónde se en el código objeto solo quedan referencias a memoria dónde se localizarían variables y rutinas … pero esto no es útil para el “dynamic localizarían variables y rutinas … pero esto no es útil para el “dynamic linker” de modo que el proceso de compilación requiere que en el linker” de modo que el proceso de compilación requiere que en el código binario queden definidas las tablas de símbolos de las código binario queden definidas las tablas de símbolos de las bibliotecas, a esto se le conoce como ABI.bibliotecas, a esto se le conoce como ABI.– API (“Application Programmer Interface”).API (“Application Programmer Interface”).

– ABI (“Application Binary Interface”).ABI (“Application Binary Interface”).

Page 20: Roger1 libreria

Generación de una biblioteca estáticaGeneración de una biblioteca estática

Pasos para generación de una biblioteca estática:Pasos para generación de una biblioteca estática:

2.2.Compilar el código fuente:Compilar el código fuente:

5.5.Condensar el código objeto de los diferentes archivos que Condensar el código objeto de los diferentes archivos que conformen la biblioteca estática:conformen la biblioteca estática:

8.8.Enlazar la biblioteca con alguna aplicación que la requiera Enlazar la biblioteca con alguna aplicación que la requiera (la aplicación requiere la declaración de prototipos o un (la aplicación requiere la declaración de prototipos o un archivo de encabezado):archivo de encabezado):

gcc –Wall –c archUnoBibEstatica.c archDosBibEstatica.c

Lo anterior producirá: archUnoBibEstatica.o y archDosBibEstatica.o

ar –cvq libBibEstatica.a archUnoBibEstatica.o archDosBibEstatica.o

Lo anterior producirá: libBibEstatica.a

gcc prog.c –L/path/to/lib -lBibEstatica

Lo anterior producirá: a.out

Page 21: Roger1 libreria

Bibliotecas de enlace dinámicoBibliotecas de enlace dinámico• Los dos tipos de bibliotecas requieren la creación de un Los dos tipos de bibliotecas requieren la creación de un código compartidocódigo compartido

(“shared object”).(“shared object”).• Este tipo de códigos ofrecen diversas ventajas:Este tipo de códigos ofrecen diversas ventajas:

– Soporte para programas que utilizan diferentes versiones de una misma biblioteca.Soporte para programas que utilizan diferentes versiones de una misma biblioteca.– Actualizaciones automáticas y renovación de versiones.Actualizaciones automáticas y renovación de versiones.– Hacer todo lo anterior mientras otros programas se ejecutan utilizando bibliotecas Hacer todo lo anterior mientras otros programas se ejecutan utilizando bibliotecas

de versiones anteriores.de versiones anteriores.

• Los objetos compartidos tienen nombres etiquetados como “fully-Los objetos compartidos tienen nombres etiquetados como “fully-qualified soname”.qualified soname”.– ““soname” soname” prefijo lib + nombre + .so + .version prefijo lib + nombre + .so + .version– ““real-name” real-name” soname + .minor_num [ + .release ] soname + .minor_num [ + .release ]– ““linker name” linker name” soname - .version soname - .version

• Es común que los nombres “soname” y para el “linker” sean ligas Es común que los nombres “soname” y para el “linker” sean ligas simbólicas al “real-name”.simbólicas al “real-name”.

Page 22: Roger1 libreria

Directorios predefinidosDirectorios predefinidos

• Normalmente los “shared objects” están ubicados Normalmente los “shared objects” están ubicados en:en:– /usr/lib … para versiones “release”./usr/lib … para versiones “release”.– /usr/local/lib … para versiones “developer”./usr/local/lib … para versiones “developer”.

• Sin embargo, la variable de ambiente Sin embargo, la variable de ambiente LD_LIBRARY_PATH puede ser utilizada para LD_LIBRARY_PATH puede ser utilizada para hacer referencia a otra carpeta, de modo que el hacer referencia a otra carpeta, de modo que el “dynamic linker” pueda encontrar la biblioteca “dynamic linker” pueda encontrar la biblioteca durante tiempo de ejecución de un programa.durante tiempo de ejecución de un programa.

Page 23: Roger1 libreria

Generación de un “shared object”Generación de un “shared object”

1.1. Crear el código objeto.Crear el código objeto.

4.4. Crear la biblioteca.Crear la biblioteca.

7.7. Instalar la biblioteca.Instalar la biblioteca.

11.11. Compilar la aplicación que requerirá a la biblioteca.Compilar la aplicación que requerirá a la biblioteca.

gcc –fPIC –c archUnoBibDinamica.c archDosBibDinamica.c

Lo anterior producirá: archUnoBibDinamica.o y archDosBibDinamica.o

gcc –shared –Wl,-soname=libBibDinamica.so.1 -o libBibDinamica.so.1.0.1 *.o

Lo anterior producirá: libBibDinamica.so.1.0.1

cp libBibDinamica.so.1.0.1 /usr/libln –sf /usr/lib/libBibDinamica.so.1.0.1 /usr/lib/libBibDinamica.soln –sf /urs/lib/libBibDinamica.so.1.0.1 /usr/lib/libBibDinamica.so.1

Lo anterior producirá dos ligas simbólicas: libBibDinamica.so y libBibDinamica.so.1

gcc –Wall –L/path/to/lib prog.c –lBibDinamica

Lo anterior producirá: a.out

Page 24: Roger1 libreria

Biblioteca de enlace dinámico explícitoBiblioteca de enlace dinámico explícito

• Requieren que el código del programa carge Requieren que el código del programa carge explícitamente el código binario de la explícitamente el código binario de la biblioteca y búsque en él las rutinas de biblioteca y búsque en él las rutinas de interés.interés.

• Las siguientes funciones son útiles para Las siguientes funciones son útiles para esto:esto:– dlopen(…)dlopen(…)– dlclose(…)dlclose(…)– dlsym(…)dlsym(…)– dlerror(…)dlerror(…)

Page 25: Roger1 libreria

Código fuente de una aplicaciónCódigo fuente de una aplicación#include <stdio.h>#include <dlfcn.h>

int main() { void *lib_handle; int (*fn)(int,int); char *error;

lib_handle = dlopen("/opt/lib/libBibCompartida.so", RTLD_LAZY); if (!lib_handle) { fprintf(stderr, "%s\n", dlerror()); return(1); }

fn = dlsym(lib_handle, "add2ints"); if ((error = dlerror()) != NULL) { fprintf(stderr, "%s\n", error); return(1); }

printf("add=%d\n",(*fn)(1,2));...

dlclose(lib_handle); return(0);}

gcc -rdynamic prog.c -ldlLo anterior producirá: a.out