Citat:
kkedacic:
Nesto slicno je i mene zanimalo prije par mjeseci, samo mene zanima kako se to inace radi od nicega?
Zanima me kako napraviti program da moze biti prosiren koristeci binary kao plugin? Ako je to uopce moguce? A ako je moguce, kako organizirati kod i na sta paziti u kodu da bi sve sljakalo? Mogu i neki primjeri u C-u, al da se radi o ELF failovima.
Pluginovi su dinamicke biblioteke. Ucitavaju se u runtime-u , program nije linkovan sa njima.
Ucitavaju se na windowsu sa LoadLibrary. Za Linux ne znam tacno.
Dobro je imati klasu koja ih ucitava. Qt ima klasu PluginLoader.
Svaki plugin treba da ima isti set eksportovanih funkcija ili ako je c++ dobro je da se eksportuje interface klasa koju interno svaki plugin implementira.
Znaci princip je da svaki plugin za taj program ima isti set funkcija koji je eksportovan (vidljiv spolja) ali u svakom pluginu te funkcije sa istim imenom rade drugu stvar. npr neki matematicki pluginovi , stavimo im fn calc() npr. plugin plus ce tu da sabere a plugin minus u toj funkciji da oduzme nesto.
Ili pluginovi za dekompresiju raznih vrsta fajlova. Za svaku vrstu jedan plugin i funkcija decompress()
Pluginovi mogu da se naknadno dodaju a da se program uopste ne menja.
Evo uopsteno neka arhitektura.
Deklarises strukturu PLUGIN npr.
Clanovi strukture neka su pointeri u koje ces moci da zapamtis adrese api funkcija jednog plugina.
Api treba da sadrzi i jednu funkciju koja vraca opis plugina u obliku teksta ili neki slican nacin da klasifikujes kakav je plugin jer to ti je jedini nacin da saznas sta neki buduci plugin radi. Recimo plugin tom funkcijom vrati "zip" i program kaze aha ovaj dekompresuje zip, sledeci plugin vrati "rar" itd.
A pritom svaki plugin ima i svoju funkciju decompress()
Zatim
Odvojis jedan c fajl za funkcije koje ucitavaju pluginove. Npr pretrazuju neki direktorijum cija je adresa relativna u odnosu na direktorijum u kome je program i pokusavaju da ucitaju sve dinamicke biblioteke iz njega.
Kada ucitaju biblioteku odvoje jednu strukturu PLUGIN i provere sve eksportovane funkcije iz ucitane biblioteke. Na windowsu kad se ucita dll mozemo da koristimo GetProcAddress da nadjemo adresu funkcije sa odredjenim imenom u ucitanoj biblioteci. Za Linux ne znam. Ako ne nadjes jednu ignorises plugin i ides dalje predhodnu petlju jer plugin ocigledno nije ok ili nije plugin. Zapamtis sve adresse u strukturi i pozoves funkciju koja vraca opis i zapamtis i to u strukturi. Predjes na sledeci plugin iz direktorijuma. Jedna struktura jedan plugin.
Ucitavanje se obicno radi samo jednom na pocetku programa.
Zato se radi ono restartovanje programa kad se doda novi plugin.
Funkcije plugina mozes kasnije da pozivas iz programa po njihovim adresama.
Sad ako pratimo ovu analogiju sa dekompresijom ... kad korisnik odabere fajl koji hoce da dekompresuje ti prvo proveris nastavak fajla i prodjes kroz sve strukture (pluginove) da vidis dali polje koje opisuje plugin sadrzi trazenu ekstenziju, drugim recima da vidis dali imas dekompresor za tu vrstu fajla. Ako imas pozoves mu funkciju decompress sa putanjom fajla kao argumentom, ako ne obavestis ...
Po ovoj arhitekturi kao sto vidis pluginovi mogu i naknadno da se dodaju a da progam ne mora da se menja niti da se kompajluje ...
U principu ovo je uobicajen nacin implementacije pluginova ...
[Ovu poruku je menjao Eurora3D Team dana 03.09.2012. u 22:49 GMT+1]