[ 2paca.zwaka @ 31.08.2012. 13:25 ] @
Interesuje me kako da napravim program koji ce moci da se prosiri nekim plugin-ovima (npr. Eclipse IDE, neke verzije Visual Studia i mnogo drugih programa...)
Radio sam dosta stvari, ali posto sada planiram razviti Open source aplikaciju za Linux i Windows (Qt ili Gtkmm sa raznim bibliotekama) zanima me kako se postize ovakva funkcionalnost.

Hvala
[ Nedeljko @ 31.08.2012. 14:47 ] @
Voleo bih da ti odgovorim, ali danas definitivno nemam vremena. Potrudiću se čim stignem da odgovorim, a ti dotle smisli neki što prostiji primer aplikacija sa plaginovima.
[ Eurora3D Team @ 01.09.2012. 01:07 ] @
Prouci Qt dokumentaciju. Qt ima razradjen framework za pravljenje pluginova, za ucitavanje itd.
Imas i primer
[ kkedacic @ 03.09.2012. 11:53 ] @
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.

[ Nedeljko @ 03.09.2012. 20:15 ] @
Formuliši neki jednostavan primer (zadatak), pa da ti na njemu pokažem.
[ Eurora3D Team @ 03.09.2012. 21:39 ] @
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]
[ Nedeljko @ 04.09.2012. 01:18 ] @
Evo u prilogu primera, kako je to Eudora3D Team zamislio.
[ mmix @ 04.09.2012. 09:46 ] @
Vazna stvar koju zaborave svi koji se zalete u implementaciju je da kad proces ucita modul, taj modul ostaje u adresnom prostoru procesa do njegovog gasenja. Ne postoji UnloadLibrary. U zavisnosti od osmisljene arhitekture pluginova to moze ali i ne mora biti problem. Za load-once i ne toliko ali moze biti problem npr ako aplikacija podrzava samo jedan modul nekog tipa a hoces da dinamicki mozes da ucitas drugi umesto njega, onda moras da imas mehanizam "smene", sto obicno provlaci neki "proxy" da bi se sprecilo setanje pointera u plugin svuda po aplikaciji
[ Mihajlo Cvetanović @ 04.09.2012. 10:00 ] @
Ne postoji UnloadLibrary, ali postoji FreeLibrary.
[ mmix @ 04.09.2012. 10:37 ] @
Da, srecno sa tim dangling pointers problemi daleko prevazilaze potrebu za oslobadjanjem malog parceta memorije. Jedna je stvar paziti na pointere funkcija i wrapovati ih u neki proxy, potpuno druga paziti na sve ostale pointere koji pucaju u DLLov adresni prostor. Posledice variraju od brljanja do toga da ti DEP obori ceo proces.
[ deerbeer @ 04.09.2012. 10:52 ] @
^ Sve sto se kreira u DLL adresnom prostoru sa new , malloc i ostalo tamo se i unistava delete , free itd ..
sto ce reci ako u interfejsu plugina imas create rutine potrebno je imati takodje i destroy/delete rutine ..
Pravilo je jako jednostavno samo ga se programeri nekad tesko pridrzavaju. :)
[ Nedeljko @ 04.09.2012. 11:33 ] @
mmix

Postoji vrlo jednostavno rešenje za to - enkapsulacija.

Modul je dizajniran kao klasa izvedena iz neke apstraktne. Funkcije koje bi išle kao promenljive su čiste virtuelne u osnovnoj klasi. Sa GetProcAddress dohvataš funkciju koja ti vraća primerak klase. Klasa može da bude singlton. Kada ti više ne treba, delete objekat, FreeLibrary modul, a onda na isti način učitaj drugi. Sve te pointere ne treba ni da vidiš, već da ti klasa obezbeđuje kompletan API, veza sa modulima je npr. globalan pokazivač na klasu koji je uvek jedan itd.
[ mmix @ 04.09.2012. 11:54 ] @
sve to vrlo brzo postane neodrzivo i sklono greskama. Dovoljno je da neki od metoda vrati char* na literal iz text segmenta u DLLu koji se negde iskopira (ptr) i vec imas nekontrolisani pointer koji ce izazvati ipf ili slicni fault kad se DLL ukloni. Potrebna je striktna disciplina, ne samo u koriscenju vec i pisanju takvih pluginova koja bas i nema neku svrhu sem "cistote" uz dalji rizik da ce neki 3rd prty da zabralja nesto svojim pluginom a da ce korisnik kriviti autora programa :).
Cak i kad je RAM problem i kad plugin napises "cisto" pritisak na RAM ce unloadovati DLLove stranice iz Working Set-a u VM usled nekoriscenja, tako da opet nista paemetno ne dobijas.
[ Mihajlo Cvetanović @ 04.09.2012. 12:10 ] @
Ako metoda ne vraća char* nego kopira sadržaj u bafer koji joj je dat onda opet nema problema.
[ mmix @ 04.09.2012. 12:12 ] @
Ili, ali pazi sad ovaj novelty, mozes da ne koristis freelibrary i da nemas nista od tih problema
[ Mihajlo Cvetanović @ 04.09.2012. 12:22 ] @
Prosleđivanje char* preko granica biblioteke mi se čini kao loša ideja bez obzira na FreeLibrary.
[ deerbeer @ 04.09.2012. 12:24 ] @
Citat:
mmix: sve to vrlo brzo postane neodrzivo i sklono greskama. Dovoljno je da neki od metoda vrati char* na literal iz text segmenta u DLLu koji se negde iskopira (ptr) i vec imas nekontrolisani pointer koji ce izazvati ipf ili slicni fault kad se DLL ukloni. Potrebna je striktna disciplina, ne samo u koriscenju vec i pisanju takvih pluginova koja bas i nema neku svrhu sem "cistote" uz dalji rizik da ce neki 3rd prty da zabralja nesto svojim pluginom a da ce korisnik kriviti autora programa :).
Cak i kad je RAM problem i kad plugin napises "cisto" pritisak na RAM ce unloadovati DLLove stranice iz Working Set-a u VM usled nekoriscenja, tako da opet nista paemetno ne dobijas.

Ukoliko je interfejs plugina napravljen kako treba ne bi trebalo da se pojavi takva greska , tj. vrlo lako se ustanovi ko je zacrao (autor programa i li 3rd party developer) tako sto ce da izbaci zadnje instalirani modul
i proveriti da li se bug i dalje pojavljuje ili neka nestabilnost u radu...
Npr ako plug-in ima metode .

Code:

Object* Create () ; 
.. / neke metode 
.. / neke metode .. 
..
void Delete (Object* obj) ; // objekat se predaje plug-inu na brisanje 

Onda problema tesko moze da bude ukoliko implementor ne zacere debelo .. recimo . ako u Create-u napravi objekat sa 'new' a u Delete ga obrise sa 'free' ...
Enkapsulacija promenljivih tj., objekata koje se prenose od plugina do exe-a i obratno je pozeljna i takvi objekti bi trebalo da kroz konstuktor/destruktor da kreiraju i brisu svoje interne pointere ukoliko ih imaju ,
i sve to u kao sto sam naveo u adresnom prostoru gde su i kreirani...
[ Nedeljko @ 04.09.2012. 12:51 ] @
mmix

Ti mu daj apstraktnu klasu koju treba samo da nasledi, a ako treba modul da vraća char*, neka klasa ima metodu koja popunjava bafer koji si mu dao zajedno sa dužinom.

Naravno, pucanje programa zbog plagina se ne može sprečiti tek tako, jer autor plagina uvek može da napiše nešto ovako:
Code (cpp):

int *p = 0;
*p = 5;

Ako ćeš da se braniš od toga, onda lepo pluginove pokreći kao zasebne procese sa kojima tvoj program komunicira.
[ Nedeljko @ 04.09.2012. 13:47 ] @
Uzgred, da priložim novu verziju programa PluginCalc sa sitnim izmenama.

On na početku učitava plaginove AddPlugin, SubPlugin i MulPlugin za vršenje računskih operacija sabiranja, oduzimanja i množenja tim redom. Zatim očekuje ulaz u obliku
arg1 operation arg2

na primer
1.4 + 2.1

i ispisuje rezultat (u pretodnom primeru 3.5).
Zatim očekuje nov ulaz, sve dok ne naiđe na operaciju koju nijedan od učitanih plaginova ne podržava, kada završava rad.

API modula se sastoji od dve funkcije, jedne za dobijanje simbola kojim se data operacija obeležava, a druge za vršenje same operacije.
[ mmix @ 04.09.2012. 14:03 ] @
Citat:
Mihajlo Cvetanović: Prosleđivanje char* preko granica biblioteke mi se čini kao loša ideja bez obzira na FreeLibrary.

Slazem se, ali svet je pun svacega. Plugin arhitektura ima malo smisla ako sve pluginove pise autor aplikacije, cemu smaranje onda. A ako ce eksterne sile da pisu pluginove onda moras da racunas na gomilu problema koje doticni mogu da izazovu, bilo da ti vrate pointer na interne strukure, bilo da ti preje*u tvoj buffer i obrisu pola data segmenta. Plugin arhitektura je najnezahvalnija od svih.

Citat:
deerbeer: Ukoliko je interfejs plugina napravljen kako treba ne bi trebalo da se pojavi takva greska , tj. vrlo lako se ustanovi ko je zacrao (autor programa i li 3rd party developer) tako sto ce da izbaci zadnje instalirani modul
i proveriti da li se bug i dalje pojavljuje ili neka nestabilnost u radu...

Hehe, da, krajnji korisnik onda raspali debugger i ulovi bug i kaze "da, nije aplikacija kriva vec plugin" :) Sve i da izbacis zadnje dodati plugin to ipak ne znaci da je plugin lose uradjen, mozda je aplikacija lose uredjena i ima unhandled ponasanje u odnosu na plugin.


Citat:
Nedeljko: Ako ćeš da se braniš od toga, onda lepo pluginove pokreći kao zasebne procese sa kojima tvoj program komunicira.

Citat:
deerbeer: Enkapsulacija promenljivih tj., objekata koje se prenose od plugina do exe-a i obratno je pozeljna i takvi objekti bi trebalo da kroz konstuktor/destruktor da kreiraju i brisu svoje interne pointere ukoliko ih imaju ,
i sve to u kao sto sam naveo u adresnom prostoru gde su i kreirani...


Da vam odgovorim obojci odjednom, to je sve bila problematika 90ih zbog koje je napravljen COM/DCOM, typelibs i COM type safety
[ deerbeer @ 04.09.2012. 14:20 ] @
Citat:

Hehe, da, krajnji korisnik onda raspali debugger i ulovi bug i kaze "da, nije aplikacija kriva vec plugin" Sve i da izbacis zadnje dodati plugin to ipak ne znaci da je plugin lose uradjen, mozda je aplikacija lose uredjena i ima unhandled ponasanje u odnosu na plugin.

Ko je to rekao ? Svaki plug-in treba da ima svoj opis (verzija i autor ) ako se radi o 3rd party developerima, i zna se kako to treba da izgleda i kakav test i kontrolu prolaze
Evo ti primer : http://www.mozilla.org/en-US/plugincheck/ pa hoce nestabilnu ili sumnjivu verziju ili plug in samo izvol'te mi ne odgovaramo.
Ako plug-in razvija samo autor onda nema ni potrebe za tim .


Citat:

Slazem se, ali svet je pun svacega. Plugin arhitektura ima malo smisla ako sve pluginove pise autor aplikacije, cemu smaranje onda. A ako ce eksterne sile da pisu pluginove onda moras da racunas na gomilu problema koje doticni mogu da izazovu, bilo da ti vrate pointer na interne strukure, bilo da ti preje*u tvoj buffer i obrisu pola data segmenta. Plugin arhitektura je najnezahvalnija od svih.

Nista onda , lepo pisi mejl Mozzili i objasni im da treba da predju na nesto drugo...


Citat:

Da vam odgovorim obojci odjednom, to je sve bila problematika 90ih zbog koje je napravljen COM/DCOM, typelibs i COM type safety

I sta hoces da kazes sa ovim ? Da smo zaostali u vremenu i prostoru i da je .NET lek za sve to
[ Chobicus @ 04.09.2012. 14:26 ] @
Citat:
2paca.zwaka:
Interesuje me kako da napravim program koji ce moci da se prosiri nekim plugin-ovima (npr. Eclipse IDE, neke verzije Visual Studia i mnogo drugih programa...)
Radio sam dosta stvari, ali posto sada planiram razviti Open source aplikaciju za Linux i Windows (Qt ili Gtkmm sa raznim bibliotekama) zanima me kako se postize ovakva funkcionalnost.

Hvala :)


Eclipse je zasnovan na OSGI platformi. Deluje da je to ono što tražiš.
[ Nedeljko @ 04.09.2012. 14:26 ] @
mmix

Ne kažem da ne postoje i takva rešenja (koja te ne spasavaju od *((int*)0)=5;), ali postoje i druga (koja rešavaju i taj problem).

Napišeš glavni program koji ne učitava nikakve plaginove i PluginManager kao zaseban program koji učitava jedan plagin koji se prosledi kao parametar komandne linije (putanja do dll-a). Glavni program nađe šta sve ima u plugin folderu i za svaki dll pokrene po jedan primerak PluginManager-a kao svoje dete sa kojim komunicira po roditelj/dete arhitekturi (dakle, ne prenose se nikakve strukture i pokazivači). Roditelj se povremeno javlja svoj svojoj deci da je živ. Svako od dece se gasi kada primeti da se roditelj ne javlja (to garantuje PluginManager). Isto tako, deca se povremeno javljaju roditelju da su živa, tako da roditelj kada primeti da se neko dete ne javlja prijavljuje korisniku koji plagin je pukao.

E, onda pucanje jednog plagina ne ruši ništa drugo i tačno se zna ko je zveknuo, tako da će i nestručnom korisniku biti jasno koga da okrivi.
[ Eurora3D Team @ 04.09.2012. 23:05 ] @
kkedacic je pitao za c jezik. Zato mu nisam pisao o klasama itd.
U principu na windowsima koliko znam dinamicka biblioteka se samo jednom ucitava u adresni prostor procesa. Svaki sledeci poziv LoadLibrary vratice adresu prvog (i jedinog) ucitanog primerka biblioteke i inkrementirace brojac za FreeLibrary.
Tom logikom i adrese funkcija ostaju iste sve dok je biblioteka ucitana.
Problem kad hocemo vise instanci.
Qt npr. ima PluginLoader klasu za ucitavanje, Pluginovi moraju da se implemetiraju po odredjenom sablonu. Svaki je u sustini interface klasa koja se interno implementira u biblioteci. Program zna samo za taj eksportovani interfejs.
Jednom mi je trebalo za potrebe programa da se ucitavaju vise instanci istog plugina i da se to uredno evidentira i dealocira.
Posto je morala da se ispostuje Qt arhtektura napravio sam metod u toj interfejs klasi koji pravi novu instancu te klase.(klase koja je nasledjuje pa kastujem u interfejs)
Tako da kad loader ucita pluginove dobijem jednu instancu od svakog plugina a sve ostale sam pravio sa tom prvom instancom ...
Znaci plugin je bio klasa u biblioteci a ne cela biblioteka.
Ne znam kako bi ovo sve moglo da se napravi u c. Mi u c++ mozemo da odvojimo objekat u klasu , svaka ima svoje promenljive itd ...
A vise instanci iste biblioteke ne mogu da se ucitaju
Isto opet ne znam ni kako to sve radi na Linuxu i dali uopste postoji neko opste resenje u c jeziku osim da imitira ovo strukturama itd.
Mozda neko zna kako je reseno u FireFoxu
[ tosa @ 05.09.2012. 01:02 ] @
Nema razlike izmedju C i C++, samo sto C++ sakriva sta se zapravo desava:
Code:

typedef struct bla {
   void (*nekafunkcija)(int nekiargument);
} nekiplugin;

Pa onda svaki DLL ima nesto tipa:
Code:

nekiplugin* createPluginInstance();

[ Eurora3D Team @ 05.09.2012. 11:19 ] @
Da u c to moze da se resi strukturama.
I ono sto bi bili clanovi klase ovde trebaju da budu clanovi strukture da bi instance imale smisla ...
[ Ivan Dimkovic @ 05.09.2012. 20:36 ] @
Najbolji nacin za plug-in mehanizam je koriscenje COM-a ili COM-olikog programianja.

Dakle, nikakva razmena C++ klasa ili C-style "hendlova" (kroz dllexport-e) vec iskljucivo virtuelnih interfejsa. Memorijski menadzment resen kroz reference-counting (AddRef/Release) i "pametne" pointere.

Mucna stvar je sto se mora raspisati dosta koda "peske" - pogotovu ako pravite neki SDK za javnu upotrebu, posto umesto koriscenja STL klasa u razmeni podataka morate koristiti vase COM ili COM-olike virtuelne interfejse ali to je one-time posao.

Sve ostalo je onda lakse.

Na kraju se moze uraditi i eksplicitno unload-ovanje DLL-ova, ako ne zelite "pravi" COM vec nesto vase, kada sve reference koje DLL pruza padnu na nulu. Za ovo ce vam biti potrebno malo glue koda koji inace COM pruza, ali to je isto one-time job, posle sve mozete da izvodite na isti nacin.

Ako je kod 100% vas i svi pluginovi ce biti 100% vasi - onda mozete ostati pri starom C-style programiranju sa razmenom hendlova tj. prikrivenih pointera na interne strukture/objekte (ala Win32 API) - ovo zahteva disciplinu i jasnu memorijsku semantiku (ko alocira / ko dealocira itd...) - ali sve dok je kod 100% vas i nemate nameru da ga delite sa drugim ovo ne mora biti problem.

Medjutim onog momenta kada taj vas plug-in mehanizam pocne da se koristi za 3rd party kod - COM ili COM-style programiranje ce vam ustedeti eone vremena u lupanju glave sta se desilo kada stvari krenu da pucaju.
[ tosa @ 06.09.2012. 08:21 ] @
^^ overengineering warning! :)
Evo jednog clanka o pisanju plugin-ova u C-u: http://eli.thegreenplace.net/2012/08/24/plugins-in-c/
[ deerbeer @ 06.09.2012. 09:29 ] @
@Ivan Dimkovic
Da , COM jeste dobro resenje, ali je vezan za Windows a cini mi se da je tema pocela oko Linux/ open source resenja ...
Moj odgovor na ovo je bio neko multiplatformsko resenje gde je programski interferjs plug-ina po standardu c/c++ -a .
Dakle , ne moze se dobiti i jare i pare :)
[ mmix @ 06.09.2012. 09:38 ] @
D-Bus?
http://www.freedesktop.org/wiki/Software/dbus

Iako je zamisljen kao RPC, ne vidim zasto ne bi mogao da se koristi kao alternativa COMu za komunikaciju unutar procesa preko session bus-a.
[ Nedeljko @ 06.09.2012. 10:32 ] @
Ispravite me ako grešim (COM ne poznajem), ali ukoliko u toj arhitekturi plagin pukne, npr. zbog ovakvog namerno napisanog koda
Code (cpp):

int *p = 0;
*p = 5;

šta se dešava sa aplikacijom? Ako je isti proces u pitanju, puče sve.
[ Ivan Dimkovic @ 06.09.2012. 10:49 ] @
Citat:
tosa: ^^ overengineering warning! :)
Evo jednog clanka o pisanju plugin-ova u C-u: http://eli.thegreenplace.net/2012/08/24/plugins-in-c/


Da li je overengineering zavisi od potreba i, IMHO, jos vaznije - ciljne grupe.

Ako ti je ciljna grupa poznata i ogranicena, predstavljaju dobre programere, nema nikakvih problema drzati se internih konvencija i koristiti jednostavan C-style plug-in sistem. Nista lakse od toga, je li.

Ako ti je ciljna grupa nepoznata (3rd party) i/ili imas komplikovan projekat za koji znas da ce evoluirati - iz nekog mog malog iskustva mogu da kazem da vredi uloziti vreme u taj "overengineering" koji ce ti smanjiti posao kasnije. Sve sto mozes da uradis sa COM-like programiranjem mozes i u cistom C-u ali ces imati vise eksplicitnih pravila kojih ce morati da se pridrzavaju svi. Koliko je to prakticno, to vrlo zavisi od okolnosti koje mozda nisu pod tvojom kontrolom :)

@Nedeljko, sve sto trci unutar istog procesa ce ti srusiti ceo proces kad pukne. Ako hoces da se stitis od toga, nema ti druge nego da napravis plug-in sistem koji plug-inove izoluje u sopstvenom procesu. Ali tada moras da resavas druge stvari - recimo IPC.

IPC k'o IPC moze da se uradi na milion nacina (pajpovi, shared-memory / virtuelni fajlovi, Win32 Window messages, DBUS, ....) ali svaki od njih nosi drugacije prednosti i mane u pogledu orgranicenja, performansi, itd...

@deerbeer - COM-style programiranje nije vezano za Windows. Koriscenje potpuno virtuelnih klasa (interfejsa) i RAII idioma se moze primeniti na svim OS-evima. Win32 COM ima glue-logiku za registraciju i ucitavanje interfejsa (i jos stosta) ali to se za tvoje potrebe moze raspisati lepo od nule tako da bude jednostavnije i verovatno brze od COM-a.

Najbolja stvar je sto onda neces morati da zavisis od kompajlera, tvoji klijenti mogu pisati pluginove u cemu hoce (bas kao sto mozes pisati COM interfejse u cemu hoces) - sve to moze i sa cistim C-om, kao sto rekoh, ali je onda onus na pridrzavanju pravila na programerima.
[ mmix @ 06.09.2012. 11:12 ] @
paaa, ima tu i jadan mali problem sa metadata. COM glue logika se bazira na IID (GUID koji jednoznacno predstavlja interfejs) i standardizovanom IUnknown interfejsu i/ili kroz kroz typelibrary i/ili kroz IDispatch, sve to opet podrzavaju drugi alati i zbog toga imas mogucnost da koristis razne alate za pisanje COM objekata, ako pravis svoj metadata sistem onda je pitanje podrske u drugim alatima realan problem. U osnovi mozes da emuliras COM (mene zapravo cudi da niko na Linux platformi nije napravio nista slicno)


Citat:
Nedeljko: Ispravite me ako grešim (COM ne poznajem), ali ukoliko u toj arhitekturi plagin pukne, npr. zbog ovakvog namerno napisanog koda


Osnovni COM (in-proc) nema tu zastitu (niti je ista moguca), access fault u COM objektu ce oboriti aplikaciju, ali COM ima tzv OLE Automation protokol (implementiran preko IDispatch koji dobijes iz IUnknown) koji barata sa Variant tipovima koji su type-safe, tako da bar deo puta imas odradjen. Kao sto je rekao Ivan, zastita je out-of-proc instancijacija objekata koju COM takodje podrzava kroz svoj proxy objekat koji enkapsulira IPC sa hsot procesom koji aktivira objekat. Sa stanovista pisanja koda sve je transparentno, samo se povecava latency poziva.


[ Eurora3D Team @ 06.09.2012. 19:47 ] @
Mislim da je ova prica o losim programerima plugina preterana ...
Koja bi to bila situacija u praksi da neko napravi los plugin, a pritom nije autor programa i da distribuira aplikaciju i plugin sirokom broju korisnika i to sve zajedno pocne da puca i puca ...
Svi mogu da prave pluginove za FireFox i da postave na Mozilinom sajtu ali to se sve testira. Oni nece da puste u download nesto sto ne valja.
[ Eurora3D Team @ 06.09.2012. 22:21 ] @
Citat:
tosa:
^^ overengineering warning! :)
Evo jednog clanka o pisanju plugin-ova u C-u: http://eli.thegreenplace.net/2012/08/24/plugins-in-c/

Ovo bi bile Linux verzije LoadLibrary i GetProcAddress
Code:
void* libhandle = dlopen(dstring_cstr(slashedpath), RTLD_NOW);
PluginInitFunc initfunc = (PluginInitFunc)
    (intptr_t) dlsym(libhandle, dstring_cstr(initfunc_name));