|
![ein Kapitel weiter](../weiter.gif)
Statische Bibliothek
Wir wissen zwar wie wir Funktionen schreiben und erstellen können. Aber irgendwann wird man
mal Funktionen die man ständig verwendet einfacher nutzen wollen. Die Routinen die sie dabei
in eigene Headerdateien stehen haben müssen aber leider ständig mitcompiliert werden.
Toll wäre es doch wenn man eigene Routinen wie die Standardheaderdateien verwenden könnte.
Für soch einen Fall müssen wir die Routinen in eine Bibliothek (Library) packen und zu unserem Projekt linken.
Eine Bibliothek ist ein Archiv von Funktionen die in übersetzter Form vorliegen und einen Index enthalten. Bibliotheken sind Objektdateien und brauchen deshalb nicht mehr zusätzlich übersetzt werden.
Um auf diese Bibliotheken Systemweit zugreifen zu können so müssen sie diese Dateien im Verzeichnis /lib (Systembibliotheken) /usr/lib (Supportbibliotheken) oder /usr/local/lib installieren. Die Headerdateien werden dabei meist im Verzeichnis /usr/include oder /usr/local/include abgelegt.
Verwenden sie ein anderes Verzeichnis wie die eben genannten, können sie dem Compiler dieses
mit den Flag -I (für Include-Dateien) und dem Flag -L (für Bibliothek-Dateien) mitteilen.
Wir wollen mit den Statischen Bibliotheken beginnen. Der Einfachheits halber verwenden wir hier einige einfache Funktionen die sie aus der Headerdatei conio.h von MS-Dos kennen dürften, die aber unter Linux/Unix nicht auf diese bekannte Weise eingesetzt werden kann.
Wenn wir Statische Bibliotheken verwenden, muss die Biblothek namentlich beim Linken
angegeben werden. So wie sie das etwa bei der Bibliothek curses.h machen....
gcc -o programm programm.c -lcurses.h
Die Vorteile von Statische Bibliotheken...
- Bibliothek-Funktionen müssen nicht immer übersetzt werden und sind nicht mehr Teil des Programms, da der Quelltext nicht mehr benötigt wird (außer der die Headerdateien). Wie dass? Sehen sie sich die Headerdatei stdio.h und die darin enthaltene Funktion printf an. Sie findnen nirgendwo den Quellcode von printf, sonderen nur desen Prototypen.
- Die Funktionen werden dem Programm hinzugefügt und stehen diesem immer zur Verfügung.
Der Nachteil von Statische Bibliotheken...
- Statische Bibliotheken benötigen mehr Speicherplatzt auf der Festplatte und im Speicher.
Das kommt daher weil sie mehrfach vorhanden sind in den Verzeichnissen der Bibliotheken
und den Programmen die diese Bibliotheken verwenden.
Zuerst wollen wir nun die Headerdatei mit den Prototypen erstellen...
/*Download:conio.h*/
#ifndef _C_MyCONIO_ #define _C_MyCONIO_
#include <stdio.h> #include <unistd.h>
#define BLACK 0 #define RED 1 #define GREEN 2 #define BROWN 3 #define BLUE 4 #define WHITE 15
/*Cursor an Position x ,y*/ void gotoxy(int x, int y);
/*Bildschirm löschen*/ void clrscr(void);
/*Linie an aktueller Position löschen*/ void delline(void);
/*Ein leere Linie an aktueller Position einfügen*/ void insline(void);
/*Textfarbe*/ void textcolor(int farbe);
/*Hintergrundfarbe*/ void textbackground(int farbe);
#endif
|
Hier haben wir nun die Headerdatei die unser Programm als Bibliothek nutzen wird. Kopieren sie diese nun in das Verzeichnis /usr/include Wahrscheinlich wird diese Aktion nur als Superuser funktionieren. Jetzt müssen wir diese Funktionen kodieren......
/*Download:conio.c*/
#include <stdio.h> #include <unistd.h>
void gotoxy(int x, int y) {
printf("\033[%d;%dH",y,x); fflush(stdout); }
void clrscr(void) {
printf("\033[H\033[J"); fflush(stdout); }
void delline(void) {
printf("\033[1M"); fflush(stdout); }
void insline(void) {
printf("\033[1L"); fflush(stdout); }
void textcolor(int farbe) {
printf("\033[2m\033[2;%d]", farbe & 0x7f); printf("\033[%dm", (farbe &0x80) ? 5 : 25); fflush(stdout); }
void textbackground(int farbe) {
printf("\033[%dm", 40+farbe%8); fflush(stdout); }
|
Speichern sie nun diese Datei unter dem Namen conio.h und erzeugen einen Objektdatei daraus....
gcc -c conio.c
Nun müsste sich eine Objektdatei in Ihrem Verzeichnis befinden (conio.o).
Als nächstes müssen wir das Archiv erstellen. Die Dateinamen beginnen dabei immer mit lib und Enden mit .a
Daraus wollen wir libconio.a machen. Dies machen wir mit dem Programm ar (Archiver), der zur Erstellung von Archiven verwendet wird. Dies machen wir mit dem Befehl..........
ar rc libconio.a conio.o
Mehr zu ar und dessen Optionen finden sie unter man ar. Nun müssen wir nur noch einen Index aller Archive vorhandenen Funtkionen machen um den Zugriff darauf zu optimieren. Dies machen wir mit....
ranlib libconio.a
Jetzt können sie die Bibliothek libconio.a in das Verzeichnis /usr/lib kopieren. Auch dies sollte nur als Superuser funktionieren. Passen sie auch die Zugriffsrechte dieser Bibliothek an. Nun wollen wir unser Programm testen....
/*Download:testco.c*/
#include <stdio.h> #include <unistd.h> #include "conio.h"
int enter(void) {
char c; gotoxy(0,0); printf("Weiter mit \n"); scanf("%c",&c); fflush(stdin); return 0; }
int main() {
clrscr(); enter(); clrscr(); enter() ; gotoxy(10,10); printf("Hallo Welt"); enter() ; delline(); gotoxy(5,10); printf("Hallo Alf"); enter(); gotoxy(5,11); printf("Hallo ET"); enter(); gotoxy(5,11); insline(); enter(); gotoxy(5,11); textcolor(RED); textbackground(BLUE); printf("--------"); enter(); clrscr(); textcolor(WHITE); textbackground(BLACK);
return 0; }
|
Speichern sie das Programm nun und übersetzen es mittels......
gcc -o programmname programmname.c -lconio
Das war alles. Jetzt stehen Ihnen immer in der Headerdatei conio.h die Funktionen zur Verfügung. Sie können jederzeit diese Headerdatei um Funktionen erweitern. Unser Flag r bei dem Archiverprogramm ar sorgt dafür das in einem bestehenden Archiv ältere Versionen der Objektdatei durch neuere Versionen ersetzt wird.
Dynamische Bibliotheken
Fast jedes Programm benutzt heute dynamische Bibliotheken, welche erst während des
Aufstartens in den Speicher geladen werden. Das heisst, das Programm, welches aufgestartet
wird, wird in den Speicher geladen, sowie die notwendigen Bibliotheken, falls diese nicht bereits im Speicher sind.
Vorteil von Dynamischen Bibliotheken.....
- Funktion wird nur einmal in den Speicher geladen dadurch......
- Programme sind kleiner, da Bibliothek nicht in den Programmcode eingebunden wird
weniger RAM-Speicher wird verschwendet, da die Bibliothek im Speicher gehalten wird und
dadurch muss weniger geswapt werden.
- Es wird nur eine Version der Bibliothek benötigt
-
Fehlerkorrektur der Bibliothek wird einfacher, da nur die Bibliothek neu übersetzt werden muss und nicht alle Programme.
Nachteile von Dynamische Bibliotheken.....
- Sollte sich die Bibliothek noch nicht im Speicher befinden muss diese zuvor geladen werden. Dadurch kann das Starten des Programms etwas länger dauern. Sind diese Bibliotheken nicht installiert, läuft das Programm nicht.
Sie können ja mal die Schreibweise Ihrer Bibliothek ansehen...
ls -l /usr/lib/lib*
Folgendermaßen setzen sich die Namen der Bibliotheken zusammen...
lrwxrwxrwx 1 root root 17 Aug 7 00:28 /usr/lib/libcurses.so -
libncurses.so.5.2*
lib<Name>
Wenn eine Funktion in der Vorgängerversion verändert oder nicht mehr unterstützt wird ist die neue Version nicht mehr abwärtskompatibel. Eine neue Funktion können sie aber ohne weiteres hinzufügen.
Nun wollen wir eine dynamische Bibliothek erstellen. Wir verwenden wieder die selben Funktionen wie schon zuvor...
/*Download:conio.c*/
#include <stdio.h> #include <unistd.h>
void gotoxy(int x, int y) {
printf("\033[%d;%dH",y,x); fflush(stdout); }
void clrscr(void) {
printf("\033[H\033[J"); fflush(stdout); }
void delline(void) {
printf("\033[1M"); fflush(stdout); }
void insline(void) {
printf("\033[1L"); fflush(stdout); }
void textcolor(int farbe) {
printf("\033[2m\033[2;%d]", farbe & 0x7f); printf("\033[%dm", (farbe &0x80) ? 5 : 25); fflush(stdout); }
void textbackground(int farbe) {
printf("\033[%dm", 40+farbe%8); fflush(stdout); }
|
Zuerst wollen wir wieder eine Objektdatei erstellen. Wir verwenden dabei den Schalter -fPIC der dafür sorgt das im Maschinencode keine festen Speicheradressen vergeben werden...
gcc -fPIC -c conio.c
PIC oder pic steht für position independent code(positionsunabhäniger Code). -fpic wird nur benutzt wenn die Bibliothek von mehreren Programmen gleichzeitig benutzt werden soll (in englisch shared), soll die erzeugte Bibliothek später dynamisch geladen werden muss man -fPIC benutzen. Jetzt können wir mit dem Compilerflag -shared die dynamische Bibliothek erstellen....
gcc -g -shared -WL,-soname,libconio.so.1 -o libconio.so.1.0 conio.o -lc
Die Erklärung der einzelnen Flags entnehmen sie bitte aus man gcc.
Nun können sie die Bibliothek libconio.so.1.0 in das Verzeichnis /usr/local/lib kopieren (Superuser). Wechseln sie nun in das Verzeichnis /usr/lib und erzeugen dort 2 Symbolische Links....
ln -sf ../local/lib/libconio.so.1.0 libconio.so.1
ln -sf libconio.so.1 libconio.so
Der 2. Symbolische Link wird benötigt für den Linker wenn sie die dynamische Bibliothek beim
Linken mit -l angeben.
Jetzt müssen sie nur noch mit ldconfig......
ldconfig /usr/lib
über die Bibliothek gehen und fertig.
Jetzt wollen wir wieder unser Beispielprogramm testen....
/*Download:testco.c*/
#include <stdio.h> #include <unistd.h> #include "conio.h"
int enter(void) {
char c; gotoxy(0,0); printf("Weiter mit \n"); scanf("%c",&c); fflush(stdin); return 0; }
int main() {
clrscr(); enter(); clrscr(); enter() ; gotoxy(10,10); printf("Hallo Welt"); enter() ; delline(); gotoxy(5,10); printf("Hallo Alf"); enter(); gotoxy(5,11); printf("Hallo ET"); enter(); gotoxy(5,11); insline(); enter(); gotoxy(5,11); textcolor(RED); textbackground(BLUE); printf("--------"); enter(); clrscr(); textcolor(WHITE); textbackground(BLACK);
return 0; }
|
Hierzu gehen wir wie folgt vor......
gcc -Wall -g -c programm.c
Jetzt linken wir unser dynamische Bibliothek zu programm.o...
gcc -g -o programm programm.o -lconio
...hinzu.
Sollten sie einmal Probleme mit einem Programm haben das nicht läuft weil etwas von
der Bibliothek fehlt können sie mit....
ldd programmname
...überprüfen welche Bibliotheken das Programm alles verwendet. Im Beispiel vom
Hello World Porgramm sieht die Ausgabe wie folgt aus..........
libc.so.6 =
/lib/ld-linux.so.2 =
Im Falle wenn ein Programm sich nicht übersetzten läßt kann dieser Befehl recht hilfreich sein. Beispiel.....
libpth.so.13 =
Hier fehlt die Bibliothek libpth.so13 damit sie das Programm ausführen können.
Dies Tutorial wurde Anhand des Betriebssystems Linux durchgeführt und sollte auf anderen Betriebssystemen ähnlich funktionieren.
![ein Kapitel weiter](../weiter.gif)
© 2001,2002 Jürgen Wolf
|