Pisanie aplikacji otwartch na wtyczki

0

Zamierzam napisać program w Delphi, który ma mieć obługę wtyczek i pluginów. Zastanawiam się, jak to zrobić? Chcę, by użytkownik (znając jakiś język programowania) mógł napisać własną wtyczkę, robiącą to, co użytkownik sobie sam wymyśli. Jak powinna wyglądać organizacja kodu aplikacji, żeby to było możliwe? Jak powinna być napisana dokumentacja do mojej aplikacji, żeby użytkownik nie miał problemów z napisaniem takiej wtyczki? Jakie funkcje powinny być udostępnione użytkownikowi? Jak powinien wyglądać plik takiej wtyczki? Jakie rady moglibyście jeszcze dać w tej sprawie?

Pozdrawiam i dziękuję za odpowiedzi :)

0

jezeli chodzi o dokumentacje etc - sa programy dajace takie mozliwosci, ja bym w nich szukal info jak dobrze to zrobic. Jezeli chodzi o organizacje kodu aplikacji - niech ktos inny Ci odpowie, na googlach tez pewnie cos znajdziesz :-D

0

Immilewski - w sumie to żeś nic nie powiedział :)

Gdy swego czasu myśleliśmy (ja, Adam Pilorz, Brodny) nad systemem wtyczek do PilotMP3 2.0 (który leży w stanie nierozpoczątym) to wybraliśmy prosty sposób - użyliśmy bibliotek DLL. Ładujemy je dynamicznie, wyszukujemy tam odpowiednie funkcje i procedury, która taka wtyczka musi posiadać, przekazujemy do nich jakieś parametry (w tej chwili nie pamiętam dokładnie co) i wykonujemy.

Program o ile pamiętam ma obsługę różnych typów wtyczek, które rozpoznaje się na podstawie tego, co odpowiednia funkcja w bibliotece zwróci, same wtyczki mają też dostęp do kilku funkcji głównego programu jak np. InternalError() ;)

Jeżeli chcesz to mogę zgrać z CVS i udostępnić obecne, bardzo stare stadium PilotMp3 1.5, gdzie trochę o tych wtyczkach jest kodu ;)

0
Ktos napisał(a)

[...] to wybraliśmy prosty sposób - użyliśmy bibliotek DLL

Szczerze mówiąc to nie spotkałem się z innym rozwiązaniem niż użycie DLL'i ;) Dodam jeszcze, że przy projektowaniu inteface'u plugina warto zadbać o to, żeby była możliwość napisania go (plugina) w innym języku niż ten w którym pisany był host (vide interface'y COM) - czyli żadne tam AnsiString'i std::string'i, TForm'y itd. jako parametry. Jasno określić konwencję wywołania metod/funkcji (na ogół __stdcall).

konik napisał(a)

Jak powinna być napisana dokumentacja do mojej aplikacji, żeby użytkownik nie miał problemów z napisaniem takiej wtyczki?

Nie opis aplikacji tylko opis interface'u plugina - co robi dana metoda/funkcja, kiedy jest wywoływana itd.

0

A jak to wygląda w programach typu Tlen itp? Tam można zrobić praktycznie wszystko, prawie całkowicie zaingerować w kod programu, tak, że później nie można poznać, co było, a czego nie było ;). Zdaje się, że Tlen ma udostępnione coś w stylu API. Chodzi mi właśnie o napisanie takiej aplikacji. Wiem, że to trudne i dlatego szukam pomocy i rad ;)

Ktos, mógłbyś "zgrać i udostępnić" PilotaMP3? Jeśli dużo to nie zajmuje, to mógłbyś mi wysłać na e-mail? Byłbym wdzięczny ;)

0
konik napisał(a)

A jak to wygląda w programach typu Tlen itp? Tam można zrobić praktycznie wszystko, prawie całkowicie zaingerować w kod programu, tak, że później nie można poznać, co było, a czego nie było ;).

Najprościej ściągnąć to API i zobaczyć ;)

Wiem, że to trudne [...]

To zależy co chcesz zrobić bo "opluginowanie" każdego elementu programu jest stratą czasu.

0

Mam to API, tyle, że nie wiem, jak zrobić coś takiego w swoim programie :P

0

A co to za program i co te pluginy (dokładnie) mają rozszerzać???

0

Program do czyszczenia różnych folderów (np TEMP) ze zbędnej zawartości ;). Chodzi o to, że program opierłby się na wtyczkach: mam wtyczkę od czyszczenia folderu temp, drugą do cookies, inną od ostatnio otwieranych dokumentów, historii FF itp. i każdy mógłby sobie napisać własną wtyczkę, która by coś robiła, czyli coś czyściła ;). Z tym już sobie poradziłem, zrobiłem na zasadzie plików dll i jest ok.

Druga sprawa to po prostu rozszerzenie funkcjonalności. Czyli na przykład użytkownik mógłby zrobić wtyczkę, która otwiera okienko, na których są wyświetlane dane nt. dysków w komputerze i tym podobne. I z tym mam problem ;)

0
konik napisał(a)

Program do czyszczenia różnych folderów (np TEMP) ze zbędnej zawartości ;). Chodzi o to, że program opierłby się na wtyczkach: mam wtyczkę od czyszczenia folderu temp, drugą do cookies, inną od ostatnio otwieranych dokumentów, historii FF itp.

A nie wydaję Ci się, że to trochę bez sensu??? Przecież prościej zrobić listę (ListView) lub drzewo (TreeView) gdzie user zaznacza które katalogi program powinien czyścić.

Druga sprawa to po prostu rozszerzenie funkcjonalności. Czyli na przykład użytkownik mógłby zrobić wtyczkę, która otwiera okienko, na których są wyświetlane dane nt. dysków w komputerze i tym podobne. I z tym mam problem ;)

Aplikacja robi listę pluginów, później z każdego plugina pobiera nazwę opcji (ISomePlugin::GetName) plus ikonę jeśli trzeba (ISomePlugin::GetMenuIcon), którą udostępnia i dodaje np. do menu - w VCL'u, w TMenuItem::Tag przypisujesz index plugina. Wszystkie dodane "itemy" w menu mają ten sam handler OnClick, w którym uruchamiasz np. metodę ISomePlugin::Execute. To który plugin został wywołany rozpoznasz po indeksie zawartym w TMenuItem::Tag. Jeżeli plugin zawiera okno to oczywiście musisz podać mu uchwyt okna-rodzica. Tyle...;)

0

ad 1) To wolę zrobić po swojemu ;)

ad 2) Jednak tu nie chodzi o zamknięty wybór możliwości dla użytkownika, ale pewną dowolność - żeby mógł wrzucić na środek buttona, który wyświetli wiadomość "bla, bla, bla", żeby mógł wrzucić jakąś formatkę przu uruchamianiu programu, dodać pozycję do popupa w tray'u i menu itd. Gdybym miał oprogramować każdą możliwość, zajęłoby mi to wieki :]

0

Szczerze mówiąc to nie spotkałem się z innym rozwiązaniem niż użycie DLL'i

Naprawdę? A XUL i JavaScript w rozszerzeniach do produktów Mozilli na przykład? :)

Dobrze, jutro ściągnę źródła PMP3 1.5 i rzucę Ci. Może się domyślisz jak to tam wygląda, bo to jest niestety wczesna bardzo wersja, nieskończona ciągle i pewnie słabo opisana. Ale część rozwiązań można podpatrzeć.

0
Ktos napisał(a)

Szczerze mówiąc to nie spotkałem się z innym rozwiązaniem niż użycie DLL'i

Naprawdę? A XUL i JavaScript w rozszerzeniach do produktów Mozilli na przykład? :)

Wiesz, chodziło mi o "tradycyjną" formę pluginów, a te z którymi się do tej pory spotykałem (grafika, audio itd.) zawsze były DLL'kami ;)

[...] Gdybym miał oprogramować każdą możliwość, zajęłoby mi to wieki

Heh już pisałem, że "opluginowanie" każdego elementu programu jest stratą czasu.

0

Moim zdaniem najlepiej jest użyć DLL'a z funkcją która pokazuje formularz. Mam coś takiego w swoim programie (BAToniku - http://adsoftware.free.pl). Można tam ściągnąc poradnik dla autorów pluginów. Czy uważacie, że to jest dobre wyjście?

0

DLL jako wtyczka ma tę wadę, że autor wtyczki może zrobić praktycznie wszystko i zwalić to na Twój program. Ale ma także ogromną zaletę - jest to stosunkowo proste do wykombinowania. Też niedawno robiłem takie cuś i wrzuciłem wtyczki jako pliki DLL + manager do zarządzania nimi jako singleton. Zawsze możesz wymyślić inne rozwiązania - jakiś język skryptowy, wtyczki jako obiekty COM czy inne tego typu udziwienia. Jak zawsze wszystko zależy od elastyczności i pomysłowości autora oraz od tego, ile czasu chce się babrać ze zrobieniem mechanizmu wtyczek.

0

konik, jesli masz troche czasu mozesz zapoznać się z architekturą narzedzia Eclipse.
Generlanie jest ono pomyslane tak aby maksymalnie uprościc tworzenie wszelkiego rodzaju wtyczek.

pzdr

0
0x666 napisał(a)
konik napisał(a)

Program do czyszczenia różnych folderów (np TEMP) ze zbędnej zawartości ;). Chodzi o to, że program opierłby się na wtyczkach: mam wtyczkę od czyszczenia folderu temp, drugą do cookies, inną od ostatnio otwieranych dokumentów, historii FF itp.

A nie wydaję Ci się, że to trochę bez sensu??? Przecież prościej zrobić listę (ListView) lub drzewo (TreeView) gdzie user zaznacza które katalogi program powinien czyścić.

To nie jest bez sensu. Wszak czyszczenie czegoś to nie zawsze wyzerowanie zawartości katalogu. Czasem trzeba zrobić coś więcej, czasem coś zostawić itp. - i do tego idealne są właśnie wtyczki odpowiedzialne za czyszczenie czegoś.

0
Adam.Pilorz napisał(a)

Wszak czyszczenie czegoś to nie zawsze wyzerowanie zawartości katalogu.

To chyba oczywiste, że program do czyszczenia dysków ZE ZBĘDNYCH plików to nie funkcja kasująca jak leci całe katalogi.

Czasem trzeba zrobić coś więcej [...]

Hmm to znaczy co więcej??? Tego typu programy mają dość proste kryteria kwalifikujące dany plik do usunięcia. Te kryteria da się przewidzieć podczas projektowania aplikacji... no chyba, że to ma być taki "program do czyszczenia dysków", który poza czyszczeniem dysków jest skanerem antywirusowym, registry cleaner'er itd. itp.

0

No to weźmy pod uwagę choćby czyszczenie cashe jakiejś przeglądarki. Jednej wystarczy wyrżnąć w pień zawartość katalogu Temporary Internet Files, a innej być może trzeba dopisać do rejestru, pliku konfiguracyjnego, albo Bóg wie jeszcze gdzie informacje o tym, że tego a tego dnia o tej i o tej godzinie Cache zostało wyczyszczone, albo usunąć z bazy danych wpisy o plikach z cachem. Takich przykładów możnaby mnożyć i mnożyć.

W tym rzecz, że aplikacja do czyszczenia dysku nie musi z góry przewidywać wszystkich możliwości. Na tym polega idea wtyczek.

0
Adam.Pilorz napisał(a)

Jednej wystarczy wyrżnąć w pień zawartość katalogu Temporary Internet Files, a innej być może trzeba dopisać do rejestru, pliku konfiguracyjnego, albo Bóg wie jeszcze gdzie informacje o tym, że tego a tego dnia o tej i o tej godzinie Cache zostało wyczyszczone [...]

Na ogół przglądarki są przygotowane na to, że czasem cache znika z bliżej nieokreślonych powodów ;) No nie oszukujmy się, niewiele jest rzeczy, które trzeba by dodatkowo wykonać przy tego typu operacjach (czyszczenie dysków).

W tym rzecz, że aplikacja do czyszczenia dysku nie musi z góry przewidywać wszystkich możliwości. Na tym polega idea wtyczek.

Heh wiem na czym polega idea wtyczek.... zresztą teraz piszę aplikację, która jest między innymi hostem dla pluginów VST.

0

Hehehe :). Trochę opuściłem ten wątek i nie zauważyłem, jak dużo odpowiedzi się pojawiło ;).

Działanie tych wtyczek nie polega na usuwaniu całej zawartości danego katalogu - to właśnie od autora wtyczki ma zależeć, jak ona będzie działała. Na przykład opróżnianie kosza - to nie jest usuwanie zawartości folderu "recycle", czy jak on tam się nazywa - bo tak się nie da. Należy wywołać odpowiednie procedury, funkcje itd. Z tymi wtyczkami 'czyszczącymi' już sobie poradziłem, i napisałem już parę i wszystko ładnie działa, niedługo może udostępnię jakąś wersję beta, czy coś i będziecie mogli zobaczyć, jak to wygląda.

Jednak nadal pozostaje kwestia wtyczek "nie czyszczących". Zacytuję siebie z jakiegoś postu wyżej:

konik napisał(a)

ad 2) Jednak tu nie chodzi o zamknięty wybór możliwości dla użytkownika, ale pewną dowolność - żeby mógł wrzucić na środek buttona, który wyświetli wiadomość "bla, bla, bla", żeby mógł wrzucić jakąś formatkę przu uruchamianiu programu, dodać pozycję do popupa w tray'u i menu itd. Gdybym miał oprogramować każdą możliwość, zajęłoby mi to wieki :]
Ta sprawa nadal pozostaje otwarta. W pewnym momencie przyszedł mi do głowy (głupi, jak się po chwili okazało :P) pomysł: co by się stało, jakby program przez jakąś funkcję udostępniał pluginowi uchwyt do formy. Jednak po głębszym zastanowieniu i przetestowaniu stwierdziłem, że to daje za małe możliwości (właściwie tylko tworzenie nowych komponentów - no chyba, że czegoś nie wiem).

0

A nie możesz napisać tego w Javie z wykorzystaniem wzorca IoC (inversion of control)? To dziala tak, że cały program składa się z samych wtyczek, a właściwie modułów, które można niezależnie testować, a później kontener konfigurowany za pomocą jednego pliku składa te moduły w jedną aplikację. Poczytaj o PicoContainer i Spring Framework. Moduły też można ładować dynamicznie. BTW. ktoś tu wspominał o Eclipse - on działa bardzo podobnie, tyle, że oni zrobili własny framework, nie używają gotowców.

DLLe są archaiczne. Nawet M$ od nich odchodzi na rzecz CLR. Latwo nimi zepsuć aplikację, nie można eksportować klas, a jedynie zwykłe funkcje, trzeba uważać na wiele aspektów technicznych jak konwencje wywołania, trzeba mieć osobny zestaw wtyczek na każdy system op., nie można w prosty sposób wyciągać listy eksportowanych funkcji (brak reflection / RTTI), są problemy z kompatybilnością bibliotek - ktoś skompiluje wtyczkę innym kompilatorem z inną wersją STLa i już wtyczka nie działa, trudno wywołać coś w programie z poziomu wtyczki (tzn. da się, ale nie tak łatwo jak w Javie) itp.

0

Jednak po głębszym zastanowieniu i przetestowaniu stwierdziłem, że to daje za małe możliwości (właściwie tylko tworzenie nowych komponentów)

Małe ??? Raczej ogromne.

Jeszcze mam taki pomysł - udostępnić wtyczce komunikaty płynące przez program. Właściwie nie trzeba udostępniać, wtyczka może założyć hook na nie. A żeby pokazać coś w tray'u wtyczka nie musi mieć żadnego dostępu do programu.

0
Krolik napisał(a)

nie można eksportować klas, a jedynie zwykłe funkcje, trzeba uważać na wiele aspektów technicznych jak konwencje wywołania [...]

A interface'y??? Wprawdzie nie można po nich dziedziczyć no ale...

trzeba uważać na wiele aspektów technicznych jak konwencje wywołania,

Z dobrą dokumentacją nie stanowi to problemu ;)

trzeba mieć osobny zestaw wtyczek na każdy system op.,

Hmm przy dobrze zaprojektowanym systemie wtyczek to też nie jest problem - tu problemem jest przenośność kodu/bibliotek jako taka.

nie można w prosty sposób wyciągać listy eksportowanych funkcji (brak reflection / RTTI)

Wystaczy jedna funkcja - class factory

są problemy z kompatybilnością bibliotek - ktoś skompiluje wtyczkę innym kompilatorem z inną wersją STLa

To stanowi problem wtedy gdy interface wtyczki odwołuje się (w parametrach) do STL'a, VCL'a itd. Na ogół stosuje się (przy definicji interface'u) tylko proste typy i/lub obiekty/interface'y zdefiniowane przez sam system wtyczek.

adf88 napisał(a)

Właściwie nie trzeba udostępniać, wtyczka może założyć hook na nie.

Ale czy wtedy będzie to wtyczka? :) Wtyczka różni się tym od rozszerzenia, że ma ściśle określone pole działania. Tu nie ma takiej "dowolności" jak w przypadku rozszerzenia.

0

@adf88
To mógłbyś mi rzucić jakimiś linkami i pomysłami? Bo jakoś sobie nie mogę wyobrazić tych ogromnych możliwości ;).

Dodam jeszcze, że ten program jest w delphi (nie wiem, czy pisałem już to wcześniej) - to pewnie ograniczy możliwości i dostępne biblioteki.

@_0x666_
Pisząc "wtyczki nie czyszczące" miałem właśnie na myśli coś w stylu rozszerzenia, sorry za wprowadzenie w błąd (używam FF i zapomniałem, że jest coś takiego, jak "rozszerzenie" :P)

0

Ja takze sklanial bym sie do interfejsow. Idea jest bardzo prosta.

  1. Musisz okreslic jak daleko uzytkownik moze sie posunac w modyfikowaniu twojego dziela.

  2. Na podstawie 1 stworzyc interfejs (to bardzo wazna czesc ! ).

  3. Przedstawic metody (a te mozna zaimplementowac w dowolnym jezyku) i prosty przyklad :)

Jako przyklad (tez czysciciela) mozna podac IEmptyVolumeCache(2) (patrz MSDN). Takie rozwiazanie ma zalete ta, ze uzytkownik zawsze musi miec zaimplementowany twoj interfejs bo inaczej program odrzuci taka wtyczke.

0

Krolik, wielkie dzięki za wspomnienie o IoC (inversion of control).
Znalazłem artykuł Fowlera na ten temat, nie czytałem jeszcze ale dla mnie to wielki autorytet więc podaję:

http://martinfowler.com/articles/injection.html

0

Aktualnie też pracuję nad systemem wtyczek do programu. Zasada działania jest bardzo prosta, program z DLL'i wczytuje strukturę wtyczki, wstawia ją do menu, a następnie pozwala elementom na wykonywanie czynności zdefiniowanych w DLL. Ograniczeń "tego co wtyczka może" praktycznie brak, no ale jak ktoś jest złośliwy i tak namiesza, a im większa swoboda w tworzeniu wtyczek, tym większe możliwości. :)</b>

0

Glowy nie dam (bo tylko rzucilem okiem), ale chyba w ostatnim miesieczniku "Software Developer's Journal 9/2006" jest artykul o tym, jak projektowac i pisac aplikacje z wtyczkami.

0
SDJournal 9/2006 napisał(a)

Warsztat
Dynamiczne rozszerzanie aplikacji C/C++
Pisanie dużych i skomplikowanych aplikacji od podstaw jest coraz rzadszym zjawiskiem. Z reguły znacznie prostsze okazuje się rozszerzanie istniejącego oprogramowania. Maciej opisuje mechanizm rozszerzania aplikacji zwanego najczęściej obsługą wtyczek (ang. plug-ins) bądź modułów.

1 użytkowników online, w tym zalogowanych: 0, gości: 1