Dinamikus csatolású függvénykönyvtár készítése és használata Plugin-szerű betöltés Egyszeű C++ osztályok készítése

Hasonló dokumentumok
Programozás C++ -ban

Programozás C++ -ban 2007/4

Programozás II gyakorlat. 4. Öröklődés

Programozás II gyakorlat. 8. Operátor túlterhelés

Bevezetés a Programozásba II 4. előadás. Adattípusok hordozhatósága

Programozás II. 4. Dr. Iványi Péter

4. Öröklődés. Programozás II

Maximum kiválasztás tömbben

Programozási alapismeretek :: beadandó feladat. Felhasználói dokumentáció. Molnár Tamás MOTIABT.ELTE

1. Alapok. Programozás II

Tartalomjegyzék. Általános Információ! 2. Felhasználói dokumentáció! 3. Feladat! 3. Környezet! 3. Használat! 3. Bemenet! 3. Példa!

C++ programok fordítása

Szerző. Varga Péter ETR azonosító: VAPQAAI.ELTE cím: Név: Kurzuskód:

Bevezetés a programozásba II. 8. Előadás: Osztályok, objektumok, osztályszintű metódusok

3. Osztályok II. Programozás II

Bevezetés a programozásba Előadás: Objektumszintű és osztályszintű elemek, hibakezelés

Programozás C nyelven FELÜLNÉZETBŐL elhullatott MORZSÁK. Sapientia EMTE

Informatikai Navigátor Érdekességek programozóknak

Visual C++ osztály készítése, adattagok, és metódusok, láthatóság, konstruktor, destruktor. Objektum létrehozása, használata, öröklés.

12. gyakorlat Enum; Tárolási osztályok Preprocesszor utasítások; Moduláris programozás

Programozás I. 5. Előadás: Függvények

500. CC Megoldó Alfréd CC 500.

117. AA Megoldó Alfréd AA 117.

Pénzügyi algoritmusok

Programozás C++ -ban 2007/7

A lista eleme. mutató rész. adat rész. Listaelem létrehozása. Node Deklarálás. Létrehozás. Az elemet nekünk kell bef zni a listába

ISA szimulátor objektum-orientált modell (C++)

Osztályok. 4. gyakorlat

500. AA Megoldó Alfréd AA 500.

Alprogramok, paraméterátadás

Statikus adattagok. Statikus adattag inicializálása. Speciális adattagok és tagfüggvények. Általános Informatikai Tanszék

0.2.1 Operátorok túlterhelése (műveletek definiálhatók felhaszn. típusokra) Kutya. Eb1. Eb2. Név (txt): Rex. Blöki. Német juhász 3

Osztály és objektum fogalma

Bevezetés a programozásba Előadás: A const

Programozási Nyelvek (C++) Gyakorlat

Bevezetés a programozásba 2

A feladat lényege egy felhasználói típusnak a zsák típusnak a megvalósítása.

Gregorics Tibor Tanácsok modularizált programok készítéséhez 1

Programozás C++ -ban

Szerző Lővei Péter LOPSAAI.ELTE IP-08PAEG/25 Daiki Tennó

Programozás II. 2. Dr. Iványi Péter

Tartalom DCOM. Történeti áttekintés. Történeti áttekintés. Történeti áttekintés. Történeti áttekintés

GPU Lab. 5. fejezet. A C++ fordítási modellje. Grafikus Processzorok Tudományos Célú Programozása. Berényi Dániel Nagy-Egri Máté Ferenc

Bevezetés a programozásba I.

STL. Algoritmus. Iterátor. Tároló. Elsődleges komponensek: Tárolók Algoritmusok Bejárók

Bevezetés a programozásba. 8. Előadás: Függvények 2.

Globális operátor overloading

Bevezetés a programozásba I.

Pénzügyi algoritmusok

Programozás II. 6.Öröklés Dr. Iványi Péter

Programozás C++ -ban

Kivételkezelés a C++ nyelvben Bevezetés

Java programozási nyelv 4. rész Osztályok II.

PROGRAMOZÁSI NYELVEK - CPP. GYAKORLAT JEGYZET

Programozás II. 2. gyakorlat Áttérés C-ről C++-ra

Szövegek C++ -ban, a string osztály

Bevezetés a programozásba I.

Pelda öröklődésre: import java.io.*; import java.text.*; import java.util.*; import extra.*;

Programozás I. gyakorlat

Egységes és objektumközpontú adatbázis-kezelés (2. rész)

Fejlett programozási nyelvek C++ Iterátorok

Pénzügyi algoritmusok

5. Gyakorlat. struct diak {

C++ programozási nyelv Konstruktorok-destruktorok

Programozás II. 3. gyakorlat Objektum Orientáltság C++-ban

128. AA Megoldó Alfréd AA 128.

Programozás II. ATM példa Dr. Iványi Péter

Programozás C++ -ban 2007/1

C++ Gyakorlat jegyzet 7. óra

Objektumok inicializálása

A C++ Standard Template Library rövid összefoglalás

Bevezetés a programozásba I 10. gyakorlat. C++: alprogramok deklarációja és paraméterátadása

500. DD Megoldó Alfréd DD 500.

Java Programozás 9. Gy: Java alapok. Adatkezelő 5.rész

Programozás II gyakorlat. 6. Polimorfizmus

- 1 - Konstansok használata. Döntsük el, van-e fordítási idejű hiba az alábbi programrészletekben! a) const char * str="zh"; str[0]++;

Emlékeztető: a fordítás lépései. Szimbólumtábla-kezelés. Információáramlás. Információáramlás. Információáramlás.

Bevezetés a programozásba Előadás: Tagfüggvények, osztály, objektum

XIII. STL. Tároló Bejáró Algoritmus. XIII.1 A vector #include <vector> #include <vector> #include <algorithm> using namespace std;

Programozási alapismeretek beadandó feladat: ProgAlap beadandó feladatok téma 99. feladat 1

PHP II. WEB technológiák. Tóth Zsolt. Miskolci Egyetem. Tóth Zsolt (Miskolci Egyetem) PHP II / 19

Objektum elvű alkalmazások fejlesztése. Öröklődés. Készítette: Sike Sándor Gregorics Tibor

Elemi alkalmazások fejlesztése III.

1. Mi a fejállományok szerepe C és C++ nyelvben és hogyan használjuk őket? 2. Milyen alapvető változókat használhatunk a C és C++ nyelvben?

Java és web programozás

Programozási nyelvek Java

Kivételek, kivételkezelés a C++ nyelvben

.AA Megoldó Alfréd AA.

C++ függelék. Tartalom

Bevezetés a programozásba Előadás: Fordítási egység

PROGRAMOZÁSI NYELVEK - CPP. ELŐADÁS JEGYZET

PROGRAMOZÁSI NYELVEK - CPP. GYAKORLAT JEGYZET

C vagy C++? Programozási Nyelvek és Fordítóprogramok Tanszék. Pataki Norbert. Programozási Nyelvek I.

Bevezetés a programozásba előadás: Öröklődés

Programozás C nyelven (3. ELŐADÁS) Sapientia EMTE

Programozási nyelvek II. JAVA EA+GY 1. gyakolat

Mobil Informatikai Rendszerek

Java programozási nyelv 5. rész Osztályok III.

és az instanceof operátor

Átírás:

FEJLETT PROGRAMOZÁSI NYELVEK, 2009 2. GYAKORLAT - Linux alatti C/C++ programozás Cél: Dinamikus csatolású függvénykönyvtár készítése és használata Plugin-szerű betöltés Egyszeű C++ osztályok készítése I. Dinamikus csatolású függvénykönyvtárak 1. Jellemzők Shared library, Dynamically Linked Library, Shared Object A dinamikus csatolású függvénykönyvtár a statikushoz hasonlóan tárgykód állományok csoportjából képződik. Amíg a statikus csatolású függvénykönyvtár használata esetén a fordító beleszerkeszti a végrehajtható állományba azon függvények kódját, amelyeket ténylegesen meghív a program, addig a dinamikus csatolású könyvtárak esetén a végrehajtható állomány csak az osztott függvénykönyvtárra való hivatkozást fog tartalmazni. Ha több végrehajtható állomány van, amely össze van kapcsolva az osztott könyvtárral, akkor mindenikük csak hivatkozást fog tartalmazni erre, magát a függvénykönyvtárat egykük sem fogja tartalmazni. Ez nagyon előnyös a végrehajtható állományok helyigénye szempontjából. Amíg a statikus csatolású függvénykönyvtár több tárgykód állomány archívuma, addig az osztott függvénykönyvtár egyetlen tárgykód állomány. Így a dinamikus csatolású függvénykönyvtár használatkor az egész csatolódik a végrehajthatóhoz. A statikus csatolás esetében csak azokat a tárgykód állományokat csatolja a fordító (szerkesztőlinker), amelyekre tényleges hivatkozás történt. 2. Készítés 1. lépés Azon forrásállományokat, amelyekből készíteni szeretnénk a függvénykönyvtárat lefordítjuk (csak compile) az fpic kapcsoló segítségével. gcc -c -fpic test1.c test2.c test3.c PIC Position-Independent Code Az osztott könyvtárbeli függvények különböző memória címekre fognak betöltődni. Ezért a kódjuk nem függhet a betöltési címtől. Erre kell emlékeztetni a fordítót az fpic kapcsoló segítségével.

2. lépés Összeszerkesztjük a megfelelően lefordított tárgykód állományokat. 3. Használat gcc -shared -fpic -o libtest.so test1.o test2.o test3.o Osztott függvénykönyvtárak használata a statikusokéhoz hasonló. Ugyanazokat a kapcsolókat használjuk az útvonal ( -L ), illetve a könyvtárnév megadására ( -l ). gcc -o main main.o -L. -ltest Ha ugyanazon függvényekből készítünk statikus és dinamikus csatolásút is, akkor a fordító azt fogja csatolni amelyiket hamarabb megtalálja, az útvonal beállításoknak megfelelően. Ha viszont ugyanabban a könyvtárban van a statikus illetve a dinamikus csatolású is, akkor a fordító a dinamikus csatolásút részesíti előnyben. A statikus csatolású iránti igényünket a static kapcsolóval nyilváníthatjuk ki. gcc -static -o main main.o -L. -ltest Az előző parancs alapján elkészül a main nevű végrehajtható állomány. Ez az állomány a main.o tárgykódfájlból készül a libtest.a függvénykönyvtár használatával. A libtest.a függvénykönyvtárat az aktuális munkakatalógusban keresi a fordító a -L. kapcsoló hatására. Ha a könyvtár fordításával minden rendben volt, a végrehajtható állományunkat is sikeresen elkészítettük, még mindig lehet egy probléma. Indításkor kaphatjuk a következő üzenetet: Cannot open shared library... Ez azt jelenti, hogy futásidőben az operációs rendszer csak a szabványos katalógusokban keresi az osztott könyvtárat. Erre a problémára a barbár megoldás az lenne, hogy bemásoljuk a könyvtárat a szabványos katalógusba (ha van írási jogosultságunk). Az elegáns megoldás pedig az, hogy kibővítjük a függvénykönyvtárak keresési útvonalát. Ez a -Wl,-rpath <utvonal> kapcsolóval adható meg. Feladat: gcc -o main main.o -L. -ltest -Wl,-rpath. Az előző órán készített stack modulból készítsen dinamikusan csatolható függvénykönyvtárat és próbálja ki a múlt órán elkészített példaprogramra. II. Dinamikus betöltés és felszabadítás (Loading and Unloading) FAKULTATÍV FELADAT Bizonyos helyzetekben futás közben szeretnénk kódot betölteni, csatolás nélkül. A betöltött kódot pedig használat után el szeretnénk távolítani. Ez a plugin modulokhoz hasonlóan működik. Linux alatt a dlopen, dlsym és dlclose függvények segítségével oldhatjuk meg a problémát. Például a libtest.so függvénykönyvtárat a következő függvénnyel tölthetjük be:

dlopen( libtest.so, RTLD_LAZY); Az RTLD_LAZY a csatolt függvénykönyvtár szimbólumaira vonatkozik és lusta betöltést jelent. Betöltés után a betöltött függvények címét a dlsym függvénnyel kaphatjuk meg. main.c FONTOS! #include <dlfcn.h>... void * handle = dlopen( libtest.so,rtld_lazy); void (*fptr)() = dlsym(handle, my_function ); (*fptr)(); dlclose(handle);... ne feledjük a programot a -ldl kapcsolóval fordítani a libdl függvénykönyvtár csatolása érdekében. fordításkor használjuk a -Wl,-rpath <katalógus> kapcsolót azért, hogy futásidőben is megtalálja a függvénykönyvtárat gcc -o main main.c -ldl -Wl,-rpath. III. Egyszerű C++ osztályok készítése Használja a Netbeans IDE-t a feladat elkészítésére! 1. Adott egy képernyőpontot ábrázoló Pont osztály. Kiemelve vannak azok a részek, amelyeket másképpen végzünk, mint Javaban: Pont.h #ifndef _PONT_H #define _PONT_H a példány adattagjaira: this mutató this->x a láthatóságokat blokkokra adjuk meg: public: alapértelmezett a private (pl. int x, y) ha egy metódus nem változtatja meg az objektum állapotát- const módosító class Pont{ int x, y; public: Pont( int x=0, int y=0){ if( x>=0 && x<=2000 ) this->x = x; else this->x = 0; if( y>=0 && y<=2000 ) this->y = y; else

this->y = 0; int getx() const{ return x; int gety() const{ return y; ; void move( int nx, int ny){ if( nx>=0 && nx<=2000 && y>=0 && y<=2000){ this->x = nx; this->y = ny; #endif /* _PONT_H */ Tanulmányozza a Pont osztály alábbi használatát és válaszoljon a következő kérdésekre: Mi a különbség a p1,p2, illetve a pp1, pp2 között? Mi a szerepe a delete operátornak? Miért nem használható a delete a p1, p2 esetében? Mi a cout? #include <cstdlib> #include <iostream> #include "Pont.h" using namespace std; int main(int argc, char** argv) { Pont p1(2,3); cout<<"p1( "<<p1.getx()<<","<<p1.gety()<<")"<<endl; Pont p2(100, 200); cout<<"p2( "<<p2.getx()<<","<<p2.gety()<<")"<<endl; Pont * pp1 = new Pont(300, 400); Pont * pp2 = new Pont(500, 1000); cout<<"pp1( "<<pp1->getx()<<","<<pp1->gety()<<")"<<endl; cout<<"pp2( "<<pp2->getx()<<","<<pp2->gety()<<")"<<endl; delete pp1; delete pp2; return (EXIT_SUCCESS);

2. Adott a következő C++ program. Futtassa és értelmezze a programot! #include <iostream> #include <iterator> #include <algorithm> #include <string> #include <vector> using namespace std; int main(int argc, char** argv) { vector<string> v; cout<<"irjon be karakterlancokat ^D vegjelig: "<<endl; copy(istream_iterator<string>(cin),istream_iterator<string>(), back_inserter(v)); sort(v.begin(), v.end()); cout<<"a kimenet:"<<endl; copy( v.begin(), v.end(), ostream_iterator<string>(cout,"\n")); return 0;