První novoroční výprodej Java týden
Hledáš brigádu v IT, která bude 100 % home office a 100 % flexibilní? Pak napiš na: redakce [zavináč] itnetwork.cz pro více info!
80 % bodů zdarma díky akci Black Friday! Tento týden rovněž sleva na e-learning Java až 80 %
Avatar
ZemiakSK
Člen
Avatar
ZemiakSK:3.8.2019 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.8.2019 22:38
Avatar
Luboš Běhounek Satik
Autoredaktor
Avatar
Luboš Běhounek Satik:3.8.2019 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.8.2019 23:52
https://www.facebook.com/peasantsandcastles/
Avatar
Martin Dráb
Redaktor
Avatar
Odpovídá na ZemiakSK
Martin Dráb:4.8.2019 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.8.2019 11:30
2 + 2 = 5 for extremely large values of 2
Avatar
DarkCoder
Člen
Avatar
Odpovídá na ZemiakSK
DarkCoder:4.8.2019 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.8.2019 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.8.2019 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.8.2019 16:57
Avatar
Odpovídá na ZemiakSK
Patrik Valkovič:4.8.2019 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.8.2019 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.8.2019 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.8.2019 17:51
Naši partneři možná hledají právě tebe!
Avatar
Luboš Běhounek Satik
Autoredaktor
Avatar
Odpovídá na ZemiakSK
Luboš Běhounek Satik:4.8.2019 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.8.2019 18:34
Nahoru Odpovědět
4.8.2019 18:33
https://www.facebook.com/peasantsandcastles/
Avatar
Martin Dráb
Redaktor
Avatar
Odpovídá na ZemiakSK
Martin Dráb:4.8.2019 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.8.2019 20:59
Akceptované řešení
+20 Zkušeností
+1 bodů
Řešení problému
Nahoru Odpovědět
4.8.2019 20:58
2 + 2 = 5 for extremely large values of 2
Avatar
ZemiakSK
Člen
Avatar
Odpovídá na Luboš Běhounek Satik
ZemiakSK:6.8.2019 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.8.2019 20:30
Avatar
ZemiakSK
Člen
Avatar
Odpovídá na Martin Dráb
ZemiakSK:6.8.2019 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.8.2019 20:32
Avatar
Martin Dráb
Redaktor
Avatar
Odpovídá na ZemiakSK
Martin Dráb:6.8.2019 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.8.2019 20:41
2 + 2 = 5 for extremely large values of 2
Avatar
ZemiakSK
Člen
Avatar
Odpovídá na Martin Dráb
ZemiakSK:7.8.2019 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.8.2019 18:34
Avatar
Martin Dráb
Redaktor
Avatar
Odpovídá na ZemiakSK
Martin Dráb:7.8.2019 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.8.2019 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.