[C con Clase] aprendiendo a crear bibliotecas

Steven Davidson srd4121 en njit.edu
Lun Nov 1 01:26:42 CET 2010


Hola Pau,

2010/10/31 Pau Marc Munoz Torres <paumarc en gmail.com>

> Hola a todos!
>
>  Hoy me he liado con el  mundo de las bibliotecas, y hay un par de cosas
> que no entiendo:
>
>
A ver si podemos aclarar las cosas.


> Segun tengo entendido se crean 2 archivos  para la biblioteca (.h y .c) mas
> el archivo que la va usar
>
>
El archivo que va a usar la biblioteca es aparte; no tiene nada que ver con
la creación de la biblioteca.

ejemplos
>
> sum.h
>
> #ifndef _SUM_H_
> #define _SUM_H_
> int sum1(int a,int b);
> #endif
>
> sum.c
>
> #include"sum.h"
> int sum1(int a,int b) {
>     return a+b;
> }
>
> primera pregunta en sum.h como se sabe cuantos guiones bajos se tienen q
> poner para el nombre de la biblioteca  en #ifndef i #define y pq no se pone


Los subrayados (o guiones bajos) forman parte del nombre de la constante
simbólica: "_SUM_H_". Puedes elegir cualquier nombre que quieras; con o sin
subrayados. Por convenio, elegimos subrayados para tener nombres más
distintivos.

sum.h en vez de _SUM_H_ en majusculas
>
>
"sum.h" es el nombre del fichero de cabecera que no tiene nada que ver con
el nombre de la constante simbólica definida y usada por las directivas del
precompilador (o preprocesador).

segunda _SUM_H_ siempre va en majusculas?
>
>
No siempre. Se trata de un nombre y por tanto, puede tener mayúsculas o
minúsculas. Nuevamente, por convenio, se usan mayúsculas.

Tercera, que diferencia habria entre _SUM_H_ i __SUM_H?
>
>
La diferencia obvia es que el segundo nombre tiene un subrayado de más al
principio. Puedes elegir cualquiera de los nombres, pero obviamente la
lógica de las directivas del precompilador debe mantenerse. Esto es,

#ifndef _SUM_H_
#define _SUM_H_

o si prefieres el otro nombre, entonces escribe:

#ifndef __SUM_H_
#define __SUM_H_

cuarta: porque en sum.c se incuye sum.h ?
>
>
La idea es separar las declaraciones de las definiciones (o
implementaciones). En el fichero de cabecera, escribimos los prototipos de
las funciones, y cualesquier otras declaraciones globales, mientras que en
el fichero fuente escribimos las implementaciones de tales funciones. El
compilador siempre compilará el fichero fuente, y no los ficheros de
cabecera.

pasemos  al ejecutable
>
> test.c
>
> #include<stdio.h>
> #include"sum.h"
> int main() {
>     printf("3+4=%i\n",sum1(3,4));
>     return 0;
> },
>
> Aqui se tiene q volver a incluir sum.h cuando ya lo habimos incluido en
> sum.c, porque? no hay otra forma mas logica? no se deberia incluir sum.c?
>
>
El compilador compila - valga la redundancia - cada fichero fuente por
separado. Como ya he mencionado, sólo compila ficheros fuente. El compilador
no puede inferir qué ficheros de cabecera quieres usar ni tampoco sabe las
entidades declaradas ni definidas en otros ficheros. Por esta razón, hay que
#incluir el fichero de cabecera "sum.h" si queremos usar 'sum1()'. De lo
contrario, el compilador te lanzará un error, porque no tiene la declaración
de 'sum1()'.

Esto lo puedes ver claramente al #incluir <stdio.h>. ¿Por qué hay que
#incluirlo? Es la misma razón, porque este fichero de cabecera contiene las
declaraciones y posiblemente algunas definiciones que necesitamos usar.

No se incluye "sum.c", porque así no es como usamos una biblioteca. Si lo
hacemos así, entonces no se trata de una biblioteca. En segundo lugar,
pueder haber "colisiones" de nombres de "sum.c" y nuestro programa en
"test.c". Algo que no es muy sencillo de solucionar.

como se compila todo esto?
>
>
La compilación, como ya he mencionado, es por cada fichero fuente
independientemente de los demás ficheros fuente. Al terminar la compilación,
el enlazador (linker, en inglés) es quien reúne todos los ficheros
compilados (llamados ficheros objeto), bibliotecas, y posiblemente otros
ficheros de otra índole para crear un fichero ejecutable o una biblioteca.

Como estás intentando crear una biblioteca, deberías haber creado un
proyecto para crear bibliotecas. Usando los dos primeros ficheros: "sum.h" y
"sum.c", construimos el proyecto. Esto implica que se compilará "sum.c", el
cual #incluye "sum.h", creando un fichero objeto: "sum.o" o posiblemente
"sum.obj". Posteriormente, el enlazador creará una biblioteca estática, que
seguramente se llamará "libsum.a" o "sum.a", o incluso, "sum.lib". Este
fichero ES la biblioteca.

Para USAR la biblioteca que acabas de crear, establece otro proyecto para
crear un programa o una aplicación y escribe el programa que quieras. En tu
ejemplo, el fichero fuente del programa es "test.c". Como quieres usar una
biblioteca externa, "sum.lib", entonces debes indicar al enlazador que use
esta biblioteca. Al construir el proyecto, se compila "test.c" (generando
"test.obj"). Posteriormente, el enlazador tomará "test.obj", "sum.lib", y
"stdlibc.lib" - o cual sea el nombre de las bibliotecas estándares, porque
#incluiste <stdio.h> - generando el fichero ejecutable, "test.exe" o como se
llame.

Sugiero que leas el artículo "Cómo crear y usar una biblioteca estática" en
nuestra página para que te hagas una idea de la creación de una biblioteca y
el uso de una biblioteca, en términos prácticos. El enlace es:
http://c.conclase.net/devcpp/index.php?cap=libestatica


Espero haber aclarado el asunto.

Steven
------------ próxima parte ------------
Se ha borrado un adjunto en formato HTML...
URL: <http://listas.conclase.net/pipermail/cconclase_listas.conclase.net/attachments/20101101/70ac82ae/attachment.html>


Más información sobre la lista de distribución Cconclase