Diskuze: Pluginy a rozšírenia pre exe aplikáciu
V předchozím kvízu, Online test znalostí C++, jsme si ověřili nabyté zkušenosti z kurzu.

Člen

Zobrazeno 14 zpráv z 14.
//= Settings::TRACKING_CODE_B ?> //= Settings::TRACKING_CODE ?>
V předchozím kvízu, Online test znalostí C++, jsme si ověřili nabyté zkušenosti z kurzu.
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.
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.
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á.
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 ?
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.
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 ?
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)
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.CreateForLibrary 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.
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 ?
Ď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 )
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í .
Diky
Ak som to pochopil správne
Či ?
Přesně tak. Najde plugin, načte jej, najde adresy funkcí z rozhraní a pak je volá dle potřeby.
Zobrazeno 14 zpráv z 14.