5
Desenvolvimento de
Bibliotecas
Sumário:
|
Tipos de bibliotecas
Há dois tipos básicos de bibliotecas:
Criação duma
biblioteca
Há duas fases principais na criação duma
biblioteca de código:
Nesta fase usa-se o compilador cc
com a opção –c.
Para uma biblioteca estática nesta fase
usa-se o arquivador ar (Linux) ou
libtool -static
(MAcOS)
Conteúdo
duma biblioteca estática
Uma biblioteca estática está dividida em três
secções:
Identifica o ficheiro referente à
biblioteca como um ficheiro arquivador (archive file)
criado por ar
É usada pelo unificador (linker)
para encontrar a localização, o tamanho e ainda informação adicional relativa a
cada rotina e a cada dado existentes na biblioteca.
Existe um para cada ficheiro objecto especificado no comando ar.
Compilação
e a construção duma biblioteca estática: libunits.a
Pretende-se construir uma biblioteca de
funções que estão contidas em três ficheiros distintos, nomeadamente: length.c, volume.c
e mass.c. Os protótipos das funções estão
contidas no ficheiro units.h
$ cc –c length.c volume.c mass.c
Exemplo de
compilação sem biblioteca:
Pretende-se, primeiro, criar um ficheiro
executável convert.exe,
cujo código fonte é o seguinte, sem recorrer a nenhuma biblioteca
$ cc
–o convert.exe convert.c length.o mass.o volume.o
$ convert.exe
O ficheiro
de protótipos units.h para a biblioteca libunits.a
Para se poder usar a biblioteca libunits.a
deverá criar um ficheiro de protótipos das funções implementadas pela
biblioteca. Seja units.h o ficheiro de
protótipos da biblioteca libunits.a.
A utilização de qualquer função desta biblioteca num
programa requer a inclusão do ficheiro units.h no
início do dito programa através da directiva #include.
Isto é necessário para que o compilador poderá verificar a correcta utilização
destas funções.
Assim se satisfaz o princípio fundamental das linguagens
imperativas: só se pode usar uma variável (ou função) se tiver sido
declarada previamente. No entanto em C a declaração duma função (o seu protótipo) não é
obrigatória embora o compilador poderá emitir um aviso caso não o encontre.
Colocação
da biblioteca libunits.a no sistema de ficheiros do
UNIX
Após a criação da biblioteca libunits.a,
há que guardá-la num local facilmente acessível a outros programadores. Existem
dois locais principais que o unificador (ou linker)
procura por defeito na fase de
junção
ou unificação do código objecto:
Colocação
do ficheiro de protótipos units.h no sistema de
ficheiros do UNIX
Após a
criação do ficheiro units.h, há que guardá-lo num local facilmente acessível a outros programadores, por exemplo numa
directoria standard
Deste
modo, qualquer programa que pretenda usar a biblioteca libunits.a,
deve fazer a inclusão do ficheiro de protótipos units.h
do seguinte modo:
·
#include <units.h>
Se, porventura, o programador não colocou o
ficheiro units.h numa das duas directorias
estandardizadas acima indicadas, mas o colocou na directoria corrente de
trabalho, a sua inclusão é feita do seguinte modo:
·
#include “units.h”
Se, o programador colocou o ficheiro units.h na directória /home/users/projects/include a sua inclusão seria feita usando as aspas onde
se pode escrever rum caminho absoluto como no exemplo em cima ou até um caminho
relativo.
·
#include
“../../users/projects/include/units.h”
Exemplo de
criação e utilização duma biblioteca estática: libunits.a
Pretende-se criar e utilizar a biblioteca libunits.a na criação dum ficheiro executável convertst.exe,
cujo código fonte é igual em tudo do ficheiro convert.sh excepto no primeiro printf:
$ ar
r libunits.a length.o volume.o mass.o
$ cc
–o convertst.exe convertst.c libunits.a
Exercícios:
·
Inserir
código para pedir ao utilizador um numero de “Pints”
e fazer a conversão para litros. (Um pint de cerveja
é um oitavo dum gallon.
·
Alterar o
constante no ficheiro length.c para o valor
2.54,actualize a biblioteca estática libunits.a e
criar de novo o executável. Para saber como substituir apenas uma parte duma
biblioteca estática consulte o “man ar”.
Criação
duma biblioteca dinâmica ou partilhada
Há duas fases principais:
Nesta fase usa-se o compilador cc
com a opção –c as vezes será necessário compilar os ficheiro com a opção –fPIC (position independent code)
Nesta fase usa-se o compilador cc
(Linux) ou libtool (Mac/Darwin).
cc –shared -fPIC -o nome_biblioteca ficheiros_objectos
Exemplo de
construção duma biblioteca estática: libunits.so
Criação
da biblioteca
$ cc – shared –fPIC –o libunits.so length.o volume.o mass.o
Nota
que pode ser necessário gerar de novo os ficheiros objectos com a opção –fpic
$ cc –fpic
–c
length.c volume.c mass.c
Exemplo de
utilização duma biblioteca dinâmica: libunits.so
Pretende-se utilizar a biblioteca libunits.a na criação dum ficheiro executável convertsh.exe,
cujo código fonte é igual em tudo do ficheiro convert.sh excepto no primeiro printf:
$ cc
–o convertsh.exe convertsh.c libunits.so
Exemplo de
execução dum programa que utilize bibliotecas dinâmicas
Problemas na execução do convertsh.exe ! Utilizar a ferramenta
ldd (otool -L no MacOs)
para investigar quais as bibliotecas partilhadas que um executável necessita e
se podem ser localizados e se se encontrem em memoria.
$ ldd convertsh.exe
Investigue a variável do shell
LD_LIBRARY_PATH para resolver qualquer problema encontrado.
$ LD_LIBRARY_PATH=$LD_LIBRARY_PATH:.
$ export LD_LIBRARY_PATH
References
http://www.tldp.org/HOWTO/Program-Library-HOWTO/index.html
http://docstore.mik.ua/orelly/linux/run/ch13_01.htm
http://www.ibm.com/developerworks/linux/library/l-dynamic-libraries/index.html
Makefile for this section