Descargamos este archivo, y nos encotramos
estos 4 archivos:
programa que usa la librería:
pru_lib_argumentos.c
makefile: genera la librería
liberia en si: argumentos.c y
argumentos.h
Abrimos el programa:
pru_lib_argumentos.c
Vemos la linea:
#include "argumentos.h"
//que hace que busque el archivo .h en
el mismo directorio donde este el programa, tambien podiamos indicar
un directorio. #include “/home/uno/argumentos.h”
struct argumentos *resul; // esta
estructura esta definica en la librería “argumentos.h”
resul = procesarArgumentos("abcdef",
argc, argv); //la funcion procesarArgumentos() le pasamos los valores
que son validos “abcdef”, y los argc y argv, que hemos recibido
de argumentos en el pograma “pru_lib_argumentos.c” y la funcion
nos devuelve la estructura resul rellena.
for(c = 0; c < resul->ar_cantNoArgs;
c++) // hace for hasta la cantidad de no argumentos (que no
empiezan el argumento por “-”, directorio, ficheros o errores de
escritura)
El programa nos muestra, los distintos
valores y el argumento que usamos.
Pasamos al fichero:
argumentos.h
Siempre que creamos una librería,
necesitamos tener un fichero de encabezado (.h), que nos va a
indicar os prototipos del contenido de la librería: funciones,
estructuras,etc
Como vemos en la primera linea “#ifndef
_ARGUMENTOS_H” (la ponemos asi para que no este definida en
ningun sitio ni por causalidad).
Y su traduccion: “si no esta definido
_ARGUMENTOS_H”
A continuación la defino:
#define _ARGUMENTOS_H, (para
que no se vuelva a definirla, y asi nos evitamos un error al intentar
incluir varias veces la misma libreria), incluyo las cabeceras que
me hacen faltan en la librería.
Si estuviese ya definido, se va al
final “#endif”
char *arg_args: puntero a tabla
de caracteres (ejemplo: “abcde”)
char **ar_noArgs: puntero a
puntero: tabla de 2 dimensiones, una lista de palabras (ejemplo:
“fichero1”, “fichero2”,”fichero3”)
De la linea 21 a la 24, se declaran las
funciones:
struct argumentos
*procesarArgumentos(char *,int, char **); // develve puntero a
una estructura argumentos y le pasamos una cadena, un numero, y una
lista de cadenas.
int argumento(char *,char *);//
devuelve un entero, y le ha pasado 2 cadenas de caracteres.
int esArgumento(char *);//
devuelve un entero, y le ha pasado 1 cadena de caracteres.
int cantidadArgumentos(int, char
**);// devuelve un entero, y le ha pasado un entero y una lista de
cadenas de caracteres.
Abrimos el archivo
“argumentos.c”:
Es donde esta el código fuente: las
descripciones de las funciones.
En la linea 3, le tenemos que poner:
#include "argumentos.h" //
estas obligado a ponerlo ya que alli se definen las funciones y las
estructuras que vamos a usar.
ar = malloc(sizeof(struct
argumentos)); // asigno espacio de memoria a la variable ar
ar->ar_args = malloc(sizeof(char));
// sizeof(char): reservo espacio para un solo carácter, por que
aunque “abcde” , ademas hay que añadirle “\0”, anque
no haya argumento.
Le doy valores iniciales a la
estructura
ar->ar_cantArgs = 0;
ar->ar_cantNoArgs = 0;
ar->ar_cantNoValidos = 0;
ar->ar_cantValidos = 0;
*(ar->ar_args) = '\0';
*(ar->ar_noArgs) = '\0';
*(ar->ar_noValidos) = '\0';
*(ar->ar_validos) = '\0';
Linea 133: definicion de la funcion
esArgumento(): devuelve si es un
argumento (empieza por “-”) 1, y si no devuelve 0
Linea 54:
while (*argu) // se repite mientras
halla letras, (hasta que llegue “\0”)
Linea 57: si valor>0, es un
argumento valido (valor = argumento(valen, argu);)
Linea 64:
tama = strlen(ar->ar_args);
// devuelve el tamaño de la cadena ar->arg_args
ar->ar_args =
realloc(ar->ar_args, sizeof(char) * (tama + 1)); // la funcion
realloc: es similar a malloc, pero amplia el tamaño de la memoria
asignada, pero reservando el contenido. “REDIMENSIONA”
Recibe 2 argumentos:
1º. El puntero al que que tiene que
reasignar memoria
2º. El tamaño que asigna.
(sizeof(char) * (tama + 1))
Nota:
REALLOC: amplia porque le digo tama+1,
tambien se puede quitar!! (tama-1)
Linea 76:
suma += valor; // es igual
suma=suma+valor
Linea 104: aumento de tabla de 2
dimensiones:
ar->ar_noArgs =
realloc(ar->ar_noArgs, sizeof(char) * (tama + 1)); // aumento el
sitio del puntero
ar->ar_noArgs[tama] = (char *)
malloc(sizeof(char) * (strlen(argu) + 1));
strcpy(ar->ar_noArgs[tama],argv[c]);
Ver esquema siguiente:
Si nos vamos a construir el programa, y
nos da el siguiente error:
Nos vamos al directorio donde ese el
programa y la librería, y le ponemos la orden: make
que busca un archivo llamado makefile,
y hace lo que ponga ese archivo.
En este archivo makefile, hace que se
construya una librería dinamica y estatica, y compila el programa
pru_lib_argumentos, creado 3 archivos:
pru_lib_argumentos_dina
pru_lib_argumentos_esta
libargumentos.so
Explicación
lo que hace makefile:
linea:
cc -Wall -I.
-I/home/julio/include -L. -L/home/julio/lib -c -o
pru_lib_argumentos.o pru_lib_argumentos.c
cc: es compilador de c (gcc es un
compilardor de c,c++, java, fortran, etc)
-Wall: que nos de los avisos
-I: indicamos el nombre de los
escritorios donde debe buscar los ficheros .h
-L: directorios donde debe de buscar
librerias.
-c: indica que solo quiero compilar, no
enlazar con la libreria
-o: indica el nombre que quiero darle
a mi programa
y luego le digo el nombre de mi
programa fuente “pru_lib_argumento.c”
Y luego le siguen 3 bloque de gcc
Tipos de librerias:
Las librerias son un grupo de funciones
pero sin el main. Al compilarlo se le dice que sea estatica o
dinamica.
esta: estatica
dina: dinamica
*************** Construyendo la
librería estática argumentos.a ***************
gcc -Wall -I. -I/home/julio/include -L.
-L/home/julio/lib -c -o argumentos.o argumentos.c
ar -rv libargumentos.a argumentos.o
ar: creating libargumentos.a
a – argumentos.o
*************** Construyendo
pru_lib_argumentos_esta ***************
gcc -o pru_lib_argumentos_esta -Wall
-I. -I/home/julio/include -L. -L/home/julio/lib pru_lib_argumentos.o
-largumentos
Se meten en el programa, y las tienes
siempre disponibles, pero que ocupa mas ya que estoy añadiendo
al programa en si, la librería dentro. Osea si son pequeñas es
bueno añadirla, pero si son grandes tu programa sera mas grande
*************** Construyendo la
librería dinámica argumentos.so ***************
gcc -Wall -I. -I/home/julio/include -L.
-L/home/julio/lib -c -o argumentos.o argumentos.c
ld -o libargumentos.so argumentos.o
-shared
rm argumentos.o
*************** Construyendo
pru_lib_argumentos_dina ***************
gcc -o pru_lib_argumentos_dina -Wall
-I. -I/home/julio/include -L. -L/home/julio/lib pru_lib_argumentos.o
-Bdynamic -largumentos
Las librerias dinámicas son librerias,
que no engordan el programa, pero hay que distribuir el programa y la
librería. Pero lo puedes reutilizar en otros programas esa librería.
El fichero que genera, siempre debe de
estar disponible: argumentos.so
Explicamos los bloque del makefile:
de argumentos.c ---> argumentos.a
***************
Construyendo la librería estática argumentos.a
***************
gcc
-Wall -I. -I/home/julio/include -L. -L/home/julio/lib -c -o
argumentos.o argumentos.c
ar
-rv libargumentos.a argumentos.o
ar:
creating libargumentos.a
a
– argumentos.o
gcc -Wall -I. -I/home/julio/include
-L. -L/home/julio/lib -c -o argumentos.o argumentos.c
De argumentos .c,
he creado argumentos.o
ar -rv libargumentos.a argumentos.o
este comando es el
que crea la librería.
“ar” es un
compresor, empaqueta todos los archivos “.o” y crear un unico
fichero “.a”
“-rv”, es un
argumento que hace que reemplaza el “.a” por los “.o”, y si
existen los reemplaza
ar: creating libargumentos.a
a – argumentos.o
Estos son mensajes
los mensajes que nos da “ar”, al ponerle el argumento “-rv”,
v=verbose, muestra los datos.
Nota:
El sistema obliba
a que el nombre el nombre empieze por “lib” y termine por
“a”
***************
Construyendo pru_lib_argumentos_esta ***************
gcc -o
pru_lib_argumentos_esta -Wall -I. -I/home/julio/include -L.
-L/home/julio/lib pru_lib_argumentos.o -largumentos
Esta linea se
encarga de enlazar (falta el “-c” al “gcc”, no lo compila)
con la librería se llama “libargumentos.a”, pero se pone
como argumento argumentos, y -l junto “-largumentos”,
y lo guarda con el nombre pru_lib_argumentos_esta.
El nombre del
programa ejecutable es: pru_lib_argumentos_esta
Ahora vemos como
lo hemos hecho para la librería dinámica.
***************
Construyendo la librería dinámica argumentos.so ***************
gcc
-Wall -I. -I/home/julio/include -L. -L/home/julio/lib -c -o
argumentos.o argumentos.c
ld
-o libargumentos.so argumentos.o -shared
rm
argumentos.o
la linea del gcc, es la misma que
cuando era estática. Obtenemos el argumentos.o
El siguiente paso: comando ld
ld
-o libargumentos.so argumentos.o -shared
ld:
comado
-o:
crear librería .so
-shared:
compartida
***************
Construyendo pru_lib_argumentos_dina ***************
gcc -o
pru_lib_argumentos_dina -Wall -I. -I/home/julio/include -L.
-L/home/julio/lib pru_lib_argumentos.o -Bdynamic -largumentos
con esta linea, el
programa ejecutable que creo es pru_lib_argmentos_dina
-Bdynamic: se mete
antes de la librería este argumento,
Nota:
Se pueden usar mas
de una librería, y de ambos tipos estaticas y dinamicas. Entonces,
para este caso, si ponemos -Bdynamic: dice que todas las
librerias que vengan a partir de ese arguentos son dinamicas y la
palabra tecnica -static: indican que apartir de ese argumento
sea estatico.
Cuando ejecutamos el compilado con
librería dinámica nos sale:
julio@julio-Aspire-5735:~/Documentos/LIBRERIAS/ej_lib$
./pru_lib_argumentos_dina
./pru_lib_argumentos_dina:
error while loading shared libraries: libargumentos.so: cannot open
shared object file: No such file or directory
julio@julio-Aspire-5735:~/Documentos/LIBRERIAS/ej_lib$
Este error es
porque no ha encontrado el archivo libargumentos.so,
ya que tiene que estar en un lugar adecuado (que solo tiene acceso el
usuario root)
Se
puede resolver de dos formas:
- Creamos una variable de entorno, llamada “LD_LIBRARY_PATH”, y ponemos la siguiente linea: (en la misma terminal donde estamos ejecutando el pru_lib_argumentos_dina)LD_LIBRARY_PATH=.export LD_LIBRARY_PATy ya podemos ejecutar el archivo: ./pru_lib_argumentos_dina
- La copiamos en el sitio adecuado: /usr/lib
No hay comentarios:
Publicar un comentario