strlen()
).
n
) po zpátku.
ulimit
změňte velikost zásobníku programu.
11, 12, 17, 21, 22, 27, 71, 72, 77
.
Výpočet Fibonacciho posloupnosti je již jednou známý a dále neměnný. Nemá smysl jej pořád implementovat odznovu, proto jej chceme zařadit do knihovny, kterou budeme přepoužívat. Chceme, aby nám knihovna uměla vypočítat $n$-tý člen posloupnosti. Deklaraci (rozhraní) této funkcionality napíšeme do hlavičkového souboru fib.h
:
int fib (int i);
Implementaci (definici) pak napíšeme do zdrojového souboru fib.c
:
#include "fib.h" int fib (int i){ ... // TODO: Implement me :-) }
Knihovnu pak můžeme použít v našem programu main.c
, který spočítá třicáté Fibonacciho číslo:
int main (){ return fib(30); }
Nyní vše stačí zkompilovat. Knihovnu zkompilujeme s přepínačem -c
, což vytvoří nespustitelný “object file” fib.o
. Druhý příkaz zkompiluje soubor main.c
a načte již hotový fib.o
a “spojí” je dohromady do spustitelného souboru main
.
gcc -c -o fib.o fib.c gcc -o main main.c fib.o ./main echo $?
fib.h
do fibit.c
, resp. fibrec.c
a zkompilujte jako sdílenou knihovnou (“shared object files”) 'libfibit.so' a 'libfibrec.so' (přepínače -fPIC -shared
).
gcc -shared -fPIC -o libfibit.so fibit.c gcc -shared -fPIC -o libfibrec.so fibrec.c
libfib.so
. (Představme si, že vývojář byl líný a implementaci “odbyl”. Do světa se proto dostala neefektivní rekurzivní varianta, kterou záhy použijeme v našem programu.)
cp libfibrec.so libfib.so
main.c
, který načte seznam čísel, a využije knihovnu fib.h
, aby pro každé načtené číslo $n$ spočítal $n$-té Fibonacciho číslo.
main.c
přeložte a slinkujte proti libfib.so
.
gcc -o main -Wl,-rpath=. -L. -lfib
ldd main
zkontrolujte, že dynamický linker správně najde naší knihovnu.
time seq 40 | main > fib_recursion.txt
cp libfibit.so libfib.so && time seq 40 | main > fib_interation.txt
readelf
se můžeme podívat, jak vypadá obsah zkompilovaných souborů pokud linkujeme staticky nebo dynamicky.
Knihovnu lze samozřejmě používat v mnoha překladových jednotkách našeho projektu. Například funkce pro práci s textovými řetězci se budou používat často a na mnoha místech. Programátorům stačí znát deklaraci knihovních funkcí v hlavičkovém souboru. Problém může nastat, pokud se deklarace z hlavičkového souboru během preprocessingu “vloží” do zdrojového kódu na více míst. Demonstrujte:
my_strlen
zabalte do knihovny my_strlen.c
s hlavičkovým souborem my_strlen.h
, který obsahuje pouze
int my_strlen(char*);
main.c
i v fibit.c
přidejte #include “my_strlen.h”
.
my_strlen.h
je proto potřeba ošetřit tuto situaci pomocí “hlídacích maker”. (Makra se mohou jmenovat jakkoliv, pokud nebudou kolidovat s jinými makry.)
#ifndef HEADER_GUARD_MY_STRLEN_H #define HEADER_GUARD_MY_STRLEN_H 1 int my_strlen(char*); #endif