Klassen aus Shared Library laden



  • Hiho,

    vor einiger Zeit bin ich über ein paar Codeschnippsel gestolpert, um mit SharedLibraries zu arbeiten. Da aus dynamischen Bibliotheken keine ganzen Klassen, sondern nur Funktionen geladen werden können, habe ich mir mal etwas gebastelt:

    https://github.com/cgloeckner/sharedclasses

    Ich habe eine Template-Klasse LibraryWrapper<T> implementiert, die (unter Win32 und Linux) aus SharedLibraries (unter Verwendung der Klassendefinition, siehe Header-Files) Konstruktor- und Destruktor-Funktionen lädt. Von ihr habe ich die Wrapper-Klasse WrappedDemo (siehe main.cpp abgeleitet und Wrapper-Funktionen (sowie Getter und Setter für die öffentliche Membervariable) geschrieben.
    Mehrere Konstruktoren werden auch unterstützt.

    Mein Problem ist, dass (siehe main.cpp) ein (aus meiner Sicht) ziemlich wildes "rumgecaste" entstanden ist:

    WrappedDemo(): LibraryWrapper<engine::Demo>("Demo", "Demo") {
        engine::Demo* (*create)() = (engine::Demo* (*)())(
            this->load_function("create_Demo")
        );
        this->data = create();
    
        std::cout << "WrappedDemo()" << std::endl;
    }
    WrappedDemo(double initwert): LibraryWrapper<engine::Demo>("Demo", "Demo") {
        engine::Demo* (*create)(double) = (engine::Demo* (*)(double))(
            this->load_function("create_Demo_double")
        );
        this->data = create(initwert);
    
        std::cout << "WrappedDemo(double)" << std::endl;
    }
    

    Hat jemand eine Idee, wie ich das eleganter löse?

    Am zweiten Beispiel erkläre ich mal (für die, die nicht gleich sehen was ich hier gemacht habe), was die paar Zeilen machen (indem ich sie anders schreibe):

    /**
     * Legt einen Funktionszeiger an, für eine Funktion mit der Signatur
     *     engine::Demo* foo(double value)
     */
    engine::Demo* (*create)(double);
    /**
     * Lädt den Funktionszeiger für die Funktion
     *     engine::Demo* create_Demo_double(double value)
     * Prinzipiell sind die Rückgabewerte geladener Funktionszeiger
     * (bei dlsym, bei der Windows-Variante kp):
     *     void*
     */
    void* create_pntr = this->load_function("create_Demo_double");
    /**
     * Daher wird der Funktionszeiger nun gecastet,
     * damit Rückgabetyp und Parameterliste korrekt sind ...
     */
    create = (engine::Demo* (*)(double))(create_pntr);
    /**
     * ... und schließlich die Funktion mit dem entsprechenden
     * Parameter aufgerufen und das Ergebnis einer Variablen
     * zugeordnet werden kann
     */
    this->data = create(initwert);
    

    Ich hoffe das Grundproblem (warum ich das hier geschrieben habe) ist deutlich geworden 🙂

    LG Glocke


Anmelden zum Antworten