Bővítmények kezelése C++-ban
2013-09-27T15:48:54+02:00
2014-01-18T17:44:53+01:00
2022-07-23T01:12:21+02:00
  • De, megpróbáltam, hisz írtam hogy működik a dolog. Egy korábbi programomat alakítottam át, ami alkatrészeket tart nyilván adatbázisban, és konzolos felületen kommunikál a felhasználóval. Most már bővítményekben vannak implementálva az egyes parancsai, keresés, törlés stb.
    Mutasd a teljes hozzászólást!
  • Szóval ez még csak elmélet, a gyakorlatban nem próbáltad még?
    Mutasd a teljes hozzászólást!
  • Újra itt vagyok. Végül sikerült megoldani amit akartam, csak az érdekelne, hogy szerintetek érdemes-e ezen az úton menni tovább.

    A megoldás három részre oszlik, van egy kliensalkalmazás, vannak a bővítmények, és van egy dinamikus objektum, amiben egy singleton osztály. A singleton osztály tartalmazza a bővítménykezelőt, és minden egyebet amit majd a program tudni fog. A könyvtár ami tartalmazza az osztályt hozzá van linkelne a kliensalkalmazáshoz is és a bővítményhez is, és mivel a az osztály singleton, ha betöltöm a bővítményt a kliensalkalmazásban, akkor ugyanazt a példányt látja majd amit a kliensalkalmazás, így a bővítmény saját magát regisztrálja a singleton osztályban, és majd a kliensalkalmazásból tudom kezelni tovább. Remélem érthető volt. Mit szóltok hozzá?
    Mutasd a teljes hozzászólást!
  • Mutasd a teljes hozzászólást!
  • Közben találtam egy unofficial Boost::Extension dolgot, ami egy bővítménykezelő és cross platform:

    csomag:
    http://svn.boost.org/svn/boost/sandbox/libs/extension/

    forrás:
    http://svn.boost.org/svn/boost/sandbox/boost/extension/

    http://boost-extension.redshoelace.com/docs/boost/extension/index.html

    A blogban azt írja a szerző, hogy tulajdonképpen kész van
    http://blog.redshoelace.com/2010/01/explanation.html
    Mutasd a teljes hozzászólást!
  • Nem mennék most bele, egyrészt mert itt off-topik, másrészt mert nem egészen triviális a dolog, és nem is egyforma a különféle unixokban (én pl. Aix-on és linux-on fejlesztgetek, és küzdök az inkompatibilitásokkal).
    Mutasd a teljes hozzászólást!
  • Én ezt nem értem. A plugint egyszerűen hozzá lehet linkelni a főprogramhoz, nem? A főprogramot nem lehet a pluginhoz, merthogy nem tudjuk, hogy lesz-e egyáltalán... A plugint ezután dlopen-el megnyitod, de ha nem exportáltad ki abból a szimbólumokat, akkor nem tudod kivenni dlsym-el, ergo nem tudsz meghívni semmit belőle.
    Mutasd a teljes hozzászólást!
  • A shared object exportált szimbólumai minden további opció nélkül dinamikusan exportálódnak, én a főprogramra utaltam az imént:

    gcc -Wl,-export-dynamic -o foprogram_that_exports_symobols_to_its_plugins ...
    Mutasd a teljes hozzászólást!
  • Szerintem ez úgy pontos, hogyha export-dynamic-al lett a plugin linkelve, akkor abból dlsym-el később el lehet kérni egy benne lévő szimbólum címét. Windows alatt meg ugye a __declspec(dllexport) kell. De az, hogy ez az egész automagic működjön, olyan nincs.
    Mutasd a teljes hozzászólást!
  • Unix-ban van olyan, hogy egy shared object rezolválhat a főprogramból ha az a -export-dynamic opcióval volt szerkesztve. Windows-ban nem tudok ilyenről.
    Mutasd a teljes hozzászólást!
  • Szerintem olyan nincs, hogy dlopen/LoadLibrary és dlsym/GetProcAddress használata nélkül lássa ugyanazt a példányt egy program és egy bővítménye. A linker feloldja fordításidőben a szimbólumokat.
    Mutasd a teljes hozzászólást!
  • Lehet, hogy arról van szó. Fórumokon még keresgéltem de nem találtam kielégítő megoldást.
    Mutasd a teljes hozzászólást!
  • Ha meg tudjuk oldani, hogy ugyanazt a példányt "lássa" a dll is és a program is a többi már nem okoz gondot.
    Mutasd a teljes hozzászólást!
  • Gondolom singletonra gondolsz a statikus osztály alatt.
    Mutasd a teljes hozzászólást!
  • > Ebből jött az ötlet, hogy kell egy statikus osztály, aminek ugyanazt a példányát látja a DLL is és az azt betöltő program is.

    És ezen túl még kell tudjon valamit ez a statikus osztály, vagy csak ennyi a specifikációja?

    PS: 'Statikus osztály' alatt olyan osztályt értesz, aminek nincsenek példányai, csak statikus metódusai és adattagjai?
    Mutasd a teljes hozzászólást!
  • Tanulmányozgattam a Code::Blocks forráskódját, és ott így csinálják a bővítmények regisztrálását a főprogramban:

    namespace { PluginRegistrant<MyPlugin> registration("MyPlugin"); }

    És ez ilyen az osztály constructora:
    PluginRegistrant(const wxString& name) { Manager::Get()->GetPluginManager()->RegisterPlugin(name, // plugin's name &CreatePlugin, // creation &FreePlugin, // destruction &SDKVersion); // SDK version }

    Megtetszett ez a megoldás, csak nem látom át teljesen. Ebből jött az ötlet, hogy kell egy statikus osztály, aminek ugyanazt a példányát látja a DLL is és az azt betöltő program is.
    Mutasd a teljes hozzászólást!
  • Miért ne adhatná át a főprogram a címet a DLL inicializáló rutinjának? De ha nem, akkor a GetModuleHandle(NULL)+GetProcAddress segíthet, ha megbeszélsz magaddal egy fix nevet (pl EztAdomAPluginnak)
    Mutasd a teljes hozzászólást!
  • Kicsit egyszerűbben: kell egy statikus osztály amelynek ugyanazt a példányát látja mind a program mind a dll amit menet közbe betöltök. És ezt anélkül, hogy át kellene adnom függvénnyel vagy hasonlóval az osztály példányát.
    Mutasd a teljes hozzászólást!
  • Csak az a része érdekel, hogy lehetséges-e olyan statikus osztályt írni ami aztán a szerver és a bővítményben is ugyanaz. Szerintetek megoldható-e ez?


    Nem biztos, hogy jól értem. Ha azt szeretnéd, hogy legyen egy osztály, ami dinamikusan betöltődik, akkor azt lehet.

    pl. van egy plugin interface-ed:


    .h #ifndef RouterPlugin #define RouterPlugin #include <string> #include <functional> namespace Plugin { typedef std::function<void (std::string&)> TCallback; struct Router { int (*select)(const std::string& str_); TCallback (*get_cb)(); }; extern Router router; } #endif .cc #include <iostream> #include "RouterPlugin.h" namespace Plugin { int select(const std::string& str_) { std::cout << "Router::select: " << str_ << std::endl; return 0; } TCallback get_cb() { return [](std::string& val) { val += "bbb"; }; } Router router = { select, get_cb }; }

    meg van egy valamid, ami használja azt:

    #include <dlfcn.h> #include <iostream> #include "RouterPlugin.h" int main() { const char* const plugin_file_name = "./librouter_plugin.so"; void* router_plugin = dlopen(plugin_file_name, RTLD_NOW); if (router_plugin == NULL) { std::cout << plugin_file_name << " not found" << std::endl; return 1; } Plugin::Router* router = static_cast<Plugin::Router*>(dlsym(router_plugin, "_ZN6Plugin6routerE")); if (router == NULL) { std::cout<< "Plugin::router not found" << std::endl; return 1; } router->select("test"); std::string test("aaa"); Plugin::TCallback cb = router->get_cb(); cb(test); cb = 0; std::cout<< "test: " << test << std::endl; dlclose(router_plugin); // cb(test); return 0; } Kimenet: Router::select: test test: aaabbb
    Mutasd a teljes hozzászólást!
  • Nézz utána, hogy a MEF mennyire elérhető C++ -hoz. A CodeProject -en is foglalkoznak vele. Nekem C# -ban eléggé bejött
    Mutasd a teljes hozzászólást!
  • Sziasztok. Régebb írogattam egy bővítménykezelőt C++-ban Windowsra. Úgy volt tervezve, hogy külön függvény adta vissza a bővítmény nevét, külön a benne definiált funkciókat vagy hogy az egyes funkcióknak mondjuk melyik menüelem lenne a megfelelője egy GUI programban. A bővítmények DLL-ek voltak. Arra gondoltam, hogy jobb lenne osztályokat használni az egészre. Az ötlet az, hogy lenne egy statikus osztály, ami eltárolná a bővítményeket és minden DLL-ben lefutna a statikus osztálynak egy függvénye ami regisztrálná a bővítményt amit utána fel lehetne dolgozni majd azt. A bővítmények lényegébe származtatott osztályok lennének és egy alap bővítményleíró osztályból származnának ami tartalmazná a nevet verziót stb. és lehetőséget ad arra hogy új funkciókat implementáljak. Csak az a része érdekel, hogy lehetséges-e olyan statikus osztályt írni ami aztán a szerver és a bővítményben i ugyanaz. Szerintetek megoldható-e ez? Vagy vannak más módszerek amik eredményesebbek?
    Mutasd a teljes hozzászólást!
abcd