C# týden November Black Friday
BlackFriday je tu! Využij jedinečnou příležitost a získej až 80 % znalostí navíc zdarma! Více zde
Pouze tento týden sleva až 80 % na e-learning týkající se C#

Diskuze: Pluginy a rozšírenia pre exe aplikáciu

Aktivity (2)
Avatar
ZemiakSK
Člen
Avatar
ZemiakSK:3. srpna 22:38

Predstavte si takúto situáciu

Nabuším kód a kompilujem ho do exe súboru . Pre príklad sa bude volať **main.exe **

A predstavte si , že by som chcel v budúcnosti rozširovať aplikáciu main.exe o nejaké ďalšie vymoženosti alebo funkcionality

Otázka znie :
Poznáte nejaký spôsob , ako upraviť aplikáciu main.exe tak , aby som ju mohol rozširovať za behu bez kompilácie ?

Dobrý príklad su pluginy do hier , napríklad pre Minecraft server
Nemusíte prepisovať samotný server , v adresári je zložka plugins , do ktorej keď plugin skopírujete a server reštartujete , tak server si plugin načíta

Dá sa niečo také urobiť aj z C++ ?

Zkusil jsem: Zatiaľ nič , ako správny plánovač som toto odkladal zo slovami "teraz to nie je podstatné , toto je dôležitejšie"

A už proste nič menej dôležité nemám :D

Prosím , nezožerte ma

 
Odpovědět
3. srpna 22:38
Avatar
Luboš Běhounek Satik
Autoredaktor
Avatar
Luboš Běhounek Satik:3. srpna 23:52

Asi nejjednodussi je udelat DLL s danou funkcnosti, pri startu nebo nejaky aktivaci pak ta aplikace v dany slozce ty DLLka hleda a pripadne loadne a zavola nejaka predem dana funkce.

Musis samozrejme veskery data tomu pluginu predat, co potrebuje.

Vetsinou se pak ta funkcnost resi pres interface, ktery ma nejaky zakladni metody jako OnStart, OnEnd, OnFrame (treba funkce volana ve hre pro kazdej snimek) a ty ti ta aplikace vola a ty v nich vykonas, co ten plugin ma delat.

Nahoru Odpovědět
3. srpna 23:52
https://www.facebook.com/peasantsandcastles/
Avatar
Martin Dráb
Redaktor
Avatar
Odpovídá na ZemiakSK
Martin Dráb:4. srpna 11:30

Je to tak, jak píše Luboš. Samozřejmě to znamená, že aplikace main.exe musí být na pluginy připravená a v určitých okamžicích svého života je volat. Může se tedy stát, že po nějaké době bys potřeboval, aby plugin pořešil něco, co mu interface nedovoluje.

Pokud se jedná o aplikaci, která na pluginy připravená není, dá se to taky, ale znamená to přepisovat kód dané aplikace v paměti, což není nic jednoduchého.

Nahoru Odpovědět
4. srpna 11:30
2 + 2 = 5 for extremely large values of 2
Avatar
DarkCoder
Člen
Avatar
Odpovídá na ZemiakSK
DarkCoder:4. srpna 12:27

Jak si sestavíš interface své aplikace, takové možnosti tvá aplikace bude mít ke své modifikaci. Interface aplikace je její srdce a zároveň jeho návrh je na tom celém to nejnáročnější.

Možností je spousta. Kromě již zmíněných DLL můžeš využívat Pipelines, vytvořit si své vlastní příkazové rozhraní, napsat aplikaci jako Interpret. Čím více dat zpřístupníš z venčí, tím více tvá aplikace bude modifikovatelná.

Nahoru Odpovědět
4. srpna 12:27
"„Učíš-li se proto, aby sis zapamatoval, zapomeneš. Učíš-li se proto, abys porozuměl, zapamatuješ si."
Avatar
ZemiakSK
Člen
Avatar
ZemiakSK:4. srpna 16:57

Lenže ako zabezpečím to prehľadávanie tej zložky ?
DLL sa includuje pomocou direktívy #include , nie ?

A tá sa odstraňuje pred samotným prekladom a nedá sa teda cykliť pomocou FOR atď.
To sa dá nejakým spôsobom vložiť do cyklu ktorý prejde obsah adresára a všetky DLL naincluduje ?

V Pythone to rieši funkcia _import_() ale tá pravdepodobne v C++ nie je , či ?

 
Nahoru Odpovědět
4. srpna 16:57
Avatar
Patrik Valkovič
Šéfredaktor
Avatar
Odpovídá na ZemiakSK
Patrik Valkovič:4. srpna 17:15

Ahoj,
pokud řešíš takové problémy, podívej se prosím nejdříve na tutoriály, které tu na ITnetworku jsou. V jednom dílu je řešeno i vyváření dynamických knihoven.
Z tvého dotazu usuzuji, že nemáš s C++ moc velké zkušenosti a dynamické načítání .dll je již pokročilé téma.

Nahoru Odpovědět
4. srpna 17:15
Nikdy neumíme dost na to, abychom se nemohli něco nového naučit.
Avatar
ZemiakSK
Člen
Avatar
Odpovídá na Patrik Valkovič
ZemiakSK:4. srpna 17:51

Ten tutorial som videl a je ta presne ten problém

V kóde musím mať tu direktívu #include "dllHlavicka.h" kde vložíme hlavičkový súbor z DLL

Ja chcem zariadiť , aby program prešiel nejaký adresár (napr. plugins) a všetky DLL automaticky načítal a zavolal funkciu z dll

V Pythone by sa to riešilo pomocou funkcie _import_() a for cyklu.
Lenže C++ nič také pravdepodobne nemá (nie som si istý , jediný spôsob ktorý som videl bol #include "niečo.h" )

Alebo proste otázka:
Dá sa v programe zariadiť , že načíta automaticky všetky DLL v nejakej zložke , ktorú si určíme ?

 
Nahoru Odpovědět
4. srpna 17:51
Tento výukový obsah pomáhají rozvíjet následující firmy, které dost možná hledají právě tebe!
Avatar
Luboš Běhounek Satik
Autoredaktor
Avatar
Odpovídá na ZemiakSK
Luboš Běhounek Satik:4. srpna 18:33

Je to vetsinou obracene, ty jako tvurce aplikace napises header, ktery pak includuji ty knihovny :)

Dynamicke nacitani dll muzes delat treba pres LoadLibrary funkci https://docs.microsoft.com/…loadlibrarya , kde zadas jmeno dll a predtim nastavis cestu pres SetDllDirectory https://docs.microsoft.com/…lldirectorya

(I kdyz dneska spis uz chces volat W verze tech funkci)

Editováno 4. srpna 18:34
Nahoru Odpovědět
4. srpna 18:33
https://www.facebook.com/peasantsandcastles/
Avatar
Martin Dráb
Redaktor
Avatar
Odpovídá na ZemiakSK
Martin Dráb:4. srpna 20:58

Alebo proste otázka:

Dá sa v programe zariadiť , že načíta automaticky všetky DLL v nejakej zložke , ktorú si určíme ?

Dá. Prostě zjistíš obsah daného adresáře (třeba plugins), k tomu můžeš využít Windows API (FindFirstFile, FindNextFile, FindClose), C++ k tomu má také nějaké funkce, ale jsou součástí až nějakého hodně nového standardu. A pak na každý takový soubor zavoláš LoadLibrary, čímž se jej systém pokusí načíst jako DLL knihovnu.

#include

Hlavičkový soubor DLL knihovny do zdrojáku dáváš proto, že obvykle obsahuje informace o typech a funkcích, které ta knihovna obsahuje. Jedná se ale o konvenci, ne o nutnost. Navíc tento způsob se využívá téměř pouze v případě (a takových případů je drtivá většina), kdy danou knihovnu nenačítáš dynamicky, ale je uvedena v závislostech (importech) tvé aplikace, a tak ji systém načte automaticky při spouštění programu.

Pro implementaci pluginů obvykle načítáš DLL knihovnu (plugin) dynamicky, což znamená, že musíš i adresy potřebných funkcí zjišťovat dynamicky. K tomu ve Windows slouží funkce GetProcAddress.

Ukázku implementace (ale bohužel v Delphi) mám třeba tady: https://github.com/…aParsers.pas

Každá DLL knihovna, která chce být pluginem, musí implementovat funkci DataParserInit, která je zavolána po jejím načtení do paměti. Ta (vyjma inicializace DLL) sdělí volajícímu potřebné informace o tom, jak plugin používat (např. předá adresy funkcí, které plugin podporuje).

Konkrétně je to ve funkci TDataParser.Cre­ateForLibrary na řádku 131 a dále. Je tedy ještě taková bezpečnostní "ochrana", která zajistí, že se opravdu načtou (a spustí) pouze DLL knihovny s funkcí DataParserInit (to je to volání LoadLibraryEx, které je hned eliminováno přes FreeLibrary).

SetDllDirectory

V tomhle případě to bude asi jedno, ale obecně nedoporučuji, protože by se ti mohlo stát, že načteš DLL knihovnu z jiného musítění, než chceš (protože ji tam někdo podstrčí). Ideálně bys měl do LoadLibrary dávat absolutní cestu, aby k takovému "omylu" dojít nemohlo.

Editováno 4. srpna 20:59
Akceptované řešení
+20 Zkušeností
+1 bodů
Řešení problému
Nahoru Odpovědět
4. srpna 20:58
2 + 2 = 5 for extremely large values of 2
Avatar
ZemiakSK
Člen
Avatar
Odpovídá na Luboš Běhounek Satik
ZemiakSK:6. srpna 20:30

Ako by sa to dalo riešiť tak ?

Ak vytvorím hlavičkový súbor ktorý človek vloží do pluginu , ako by sa o tom dozvedela .exe aplikácia a ten plugin by zahrnula ?

Nejaký stručný popis ako by to fungovalo ?
Nejaká trieda v plugine bude dediť moju triedu , či ?

 
Nahoru Odpovědět
6. srpna 20:30
Avatar
ZemiakSK
Člen
Avatar
Odpovídá na Martin Dráb
ZemiakSK:6. srpna 20:32

Ďakujem za zaujímavé funkcie , ktoré by som mohol použiť

Len sa spýtam či neexistujú podobné funkcie , ktoré sa daju použiť pre windows aj pre linux (ale to už by som asi chcel moc )

 
Nahoru Odpovědět
6. srpna 20:32
Avatar
Martin Dráb
Redaktor
Avatar
Odpovídá na ZemiakSK
Martin Dráb:6. srpna 20:41

Pro Linux můžeš použít tyto. Možná budou i přenositelné na Windows podobně, jako třeba funkce printf. Resp. existuje nějaká přenositelná varianta (myslím), ale nemůžu si teď vzpomenout na názvy těch funkcí :-).

http://tldp.org/…braries.html

Nahoru Odpovědět
6. srpna 20:41
2 + 2 = 5 for extremely large values of 2
Avatar
ZemiakSK
Člen
Avatar
Odpovídá na Martin Dráb
ZemiakSK:7. srpna 18:34

Diky

Ak som to pochopil správne

  • uživatel si vytvorí plugin ktorý bude mať rozhranie podla dokumentácie
  • exe aplikácia ho nájde , načíta funkciu a získa jej adresu

Či ?

 
Nahoru Odpovědět
7. srpna 18:34
Avatar
Martin Dráb
Redaktor
Avatar
Odpovídá na ZemiakSK
Martin Dráb:7. srpna 20:35

Přesně tak. Najde plugin, načte jej, najde adresy funkcí z rozhraní a pak je volá dle potřeby.

Nahoru Odpovědět
7. srpna 20:35
2 + 2 = 5 for extremely large values of 2
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 14 zpráv z 14.