6. gyakorlat
Kapcsolódó tananyagok¶
- C fordítás lépései, azon belül is linkelés
Órai feladatok¶
Órai segédletek
-
Egyre nagyobb a kódunk, egyre kezelhetetlenebb, nem átlátható! Tudunk beolvasni színes képet, szürkeárnyalatosat, de igaziból mindez egy felhasználó szempontjából részletkérdés, ő elégedett azzal, ha tud KÉPET beolvasni, és az implementációs részletek nincsenek az orrára kötve. Első lépésben szervezzük ki a fő programból mindazt, ami a képkezeléshez tartozik! Ezt is persze tegyük több lépésben!
-
Minden típus definiálást mozgassunk át egy
types.hnevű állományba! Amikor egy header állományt készítünk, fontos lépés, hogy biztosítsuk azt, hogy a header tartalma nem kerül többször behúzásra! Ezt a következő módon érhetjük el!1 2 3 4 5 6
#ifndef TYPES_H #define TYPES_H // ide kell írni a kódot (jelen esetben a típusdefiníciókat!) #endif -
Mozgassuk a PGM képkezelő metódusokat a
pgm.cfájlba! Készítsünk mellé egypgm.hállományt is, ami pedig a metódusok fejléceit adja meg! Ne felejtsük el, hogy itt is használni kell az előbbi feladat trükkjét, illetve include-olni kell atypes.h-t! Ha jól dolgoztunk, agcc -o pgm.o -c pgm.clefordítja az állományt és elkészül a megfelelő object fájl. - Ismételjük meg az előbbi feladatot a PPM metódusokra, értelemszerűen ezeket a
ppm.césppm.hállományokba tegyük! -
Készítsünk egy
image.h-t és egyimage.c-t, amiben hasonlóan az előzőekhez, de amibe az általános képkezelő metódusok tartozzanak! Mit kell include-olni, és hol? Igyekezzünk minél kevesebb include műveletet tenni a header állományba! -
Ha elkészült a fenti 3 object, akkor állítsunk elő ezekből egy úgynevezett archive fájlt!
1ar rcs libimage.a image.o pgm.o ppm.o -
Ezután fordítsuk a fő programot, amelyhez az előbb készült archive fájlt statikusan linkeljük!
1gcc -o prog_static main.o -L. -limage -static -
Nézzük meg, mekkora lett az elkészült bináris, illetve hogy milyen szimbólumokat tartalmaz! Használd az
ls,nmvagyreadelf -sparancsokat! -
Fordítsuk le egy kicsit másképp az állományainkat, és készítsünk egy dinamikusan linkelhető shared object fájlt és ezzel linkeljük a fő programot!
1 2 3 4 5
gcc -fPIC -c image.c gcc -fPIC -c pgm.c gcc -fPIC -c ppm.c gcc -shared -o libimage.so image.o pgm.o ppm.o gcc -o prog_dyn main.c -L. -limage -
Mi történik, ha a shared object fájlt elmozgatjuk egy másik könyvtárba? Tudjuk-e most futtatni a programot?
-
Állítsuk be az
LD_LIBRARY_PATHkörnyezeti változót arra a könyvtárra, amibe mozgattuk az so fájlt! Próbáljuk újra futtatni a binárist! Sikerül-e? -
Milyen előnyei/hátrányai vannak a statikus és dinamikus linkelésnek? Érveljünk egyik, majd a másik mellett/ellene!
-
Töltsük le a Makefile fájlt és próbáljuk ki, hogyan tudjuk segítségével előállítani, könnyebben fordítani a programunkat, vagy komponenseit! Használjuk a következő parancsokat! Próbáljuk ki, hogy csak egy-egy állományt módosítunk kicsit! Mi történik?
1 2 3
make clean make prog_static make prog_dyn - (Haladóknak) A fő programban ottmaradt egy segédfüggvény, ami igaziból nem biztos, hogy itt kellene legyen! Próbáljuk meg elrejteni a külső felhasználó elől! Írjuk át úgy a programot, hogy ezt a függvényt csak az
image.c-ben lássuk!
Gyakorló feladatok¶
- Hozz létre egy típust háromdimenziós pontok tárolására! Készíts egy függvényt, ami két ilyen térbeli pont távolságát adja vissza, valamint egy
függvényt, ami három oldalhossz alapján kiszámolja egy háromszög területét! A fenti programelemekből készíts egy modulként használható
lib.héslib.cpárost! Ezek után írj egytetra.cnevű programot ami négy háromdimenziós koordináta-hármasból kiszámítja egy pontok által határolt térrész (egyfajta szabálytalan "tetraéder", oldalaikkal és csúcsaikkal érintkező négy háromszög által határolt test, melynek csúcsai a megadott pontok) felszínét! A szükséges adatokat a program parancssori paraméterként kapja meg.