Kihagyás

6. gyakorlat

Kapcsolódó tananyagok

  • C fordítás lépései, azon belül is linkelés

Órai feladatok

Órai segédletek
  1. 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!

  2. Minden típus definiálást mozgassunk át egy types.h nevű á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
    

  3. Mozgassuk a PGM képkezelő metódusokat a pgm.c fájlba! Készítsünk mellé egy pgm.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 a types.h-t! Ha jól dolgoztunk, a gcc -o pgm.o -c pgm.c lefordítja az állományt és elkészül a megfelelő object fájl.

  4. Ismételjük meg az előbbi feladatot a PPM metódusokra, értelemszerűen ezeket a ppm.c és ppm.h állományokba tegyük!
  5. Készítsünk egy image.h-t és egy image.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!

  6. Ha elkészült a fenti 3 object, akkor állítsunk elő ezekből egy úgynevezett archive fájlt!

    1
    ar rcs libimage.a image.o pgm.o ppm.o
    

  7. Ezután fordítsuk a fő programot, amelyhez az előbb készült archive fájlt statikusan linkeljük!

    1
    gcc -o prog_static main.o -L. -limage -static
    

  8. Nézzük meg, mekkora lett az elkészült bináris, illetve hogy milyen szimbólumokat tartalmaz! Használd az ls, nm vagy readelf -s parancsokat!

  9. 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
    

  10. Mi történik, ha a shared object fájlt elmozgatjuk egy másik könyvtárba? Tudjuk-e most futtatni a programot?

  11. Állítsuk be az LD_LIBRARY_PATH kö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?

  12. Milyen előnyei/hátrányai vannak a statikus és dinamikus linkelésnek? Érveljünk egyik, majd a másik mellett/ellene!

  13. 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
    

  14. (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

  1. 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 és lib.c párost! Ezek után írj egy tetra.c nevű 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.