Eigene Programmbibliothek zur Laufzeit laden

Schnelle objektorientierte, kompilierende Programmiersprache.
Glocke
Beiträge: 332
Registriert: Fr Okt 26, 2012 8:39 am

Re: Eigene Programmbibliothek zur Laufzeit laden

Beitrag von Glocke » Di Jan 08, 2013 9:27 pm

Vielmals sorry für das gepastebinne - Xin hatte es in einem anderen Thread schon angesprochen, aber seit dem kam ich nicht nochmal dazu zu posten.

Also, der aktuelle Stand ist im Anhang. Das Shell-Skript build.sh kann mit ./build.sh lib dazu verwendet werden, die Shared Library zu erstellen, mit ./build.sh app für die Demo-Anwendung und ./build.sh test baut das Programm, zum Testen der Demo.hpp und Demo.cpp, in dem der Code direkt eingebunden wird. Dabei habe ich aberin der Demo.cpp die main-Funktion auskommentiert.

Kurz:

Code: Alles auswählen

./build.sh lib
./build.sh app
./main
... das baut und startet den Test für die Shared Library.

Im Ordner core gibt es eine LibraryWrapper.hpp, mit der Template-Klasse LibraryWrapper<T>, die als Typparameter die zu ladende Klasse (Demo aus der Demo.hpp) bekommt. In der main.cpp habe ich eine Klasse WrappedDemo implementiert, die auf LibraryWrapper<Demo> basiert und Wrapper-Funktionen für die öffentlichen Member enthält.

Das mit den gewrappten Methoden und Gettern / Settern ist noch etwas umständlich, funktioniert aber erstmal. Hat jemand eine Idee, wie ich das ohne mache? LibraryWrapper<T> von T abzuleiten sollte die Member direkt zur Verfügung stellen, allerdings bekomme ich dann den Konstruktor nicht korrekt aufgerufen.

Außerdem habe ich bisher noch keine gute Idee, wie ich verschiedene Konstruktoren am besten implementiere. Bisher fällt mir nur ein, verschiedene "Konstruktor-Funktionen" (wie create_Demo_int (Konstruktor mit 1x int), create_Demo_int_int (Konstruktor mit 2x int), create_Demo_int_float (Konstruktor mit 1x int und 1x float) usw.) zu implementieren, und in WrappedDemo mehrere Konstruktoren zu implementieren, die verschiedene "Konstruktor-Funktionen" aus der Lib laden und mit Parametern füttern. Dabei müsste ich allerdings umgehen, dass LibraryWrapper<T> den Standardkonstruktor (sei jetzt mal create_Demo) aufzurufen... Hat da jemand eine Idee?

LG Glocke

/EDIT: Wahlweise: https://github.com/Glocke89/sharedclasses
Du hast keine ausreichende Berechtigung, um die Dateianhänge dieses Beitrags anzusehen.

Benutzeravatar
fat-lobyte
Beiträge: 1398
Registriert: Sa Jul 05, 2008 12:23 pm
Wohnort: ::1
Kontaktdaten:

Re: Eigene Programmbibliothek zur Laufzeit laden

Beitrag von fat-lobyte » Mi Jan 09, 2013 12:14 am

Glocke hat geschrieben:/EDIT: Wahlweise: https://github.com/Glocke89/sharedclasses
Super, von mir zwei Daumen! b d
So einfach geht das.
Haters gonna hate, potatoes gonna potate.

Glocke
Beiträge: 332
Registriert: Fr Okt 26, 2012 8:39 am

Re: Eigene Programmbibliothek zur Laufzeit laden

Beitrag von Glocke » Mi Jan 09, 2013 9:12 am

So, mehrere Konstruktoren sind jetzt möglich :)

Dabei wird statt "create_Demo" (Standardkonstruktor) einfach der Parameter rangehangen, um einen - für das Laden mit dlsym - eindeutigen Funktionsnamen zu haben.
Dann müssen nur noch die Konstruktoren von WrappedDemo implementiert werden, so dass sie den Oberklassekonstruktor aufrufen (der lädt nur noch die Shared Lib sofern nötig) und dann muss (im Wrapped-Konstruktor) die entsprechende Funktion geladen, der Funktionszeiger "zurechtgecastet" und die Funktion aufgerufen werden.
Der Punkt ist noch etwas hässlich :-S

LG

Glocke
Beiträge: 332
Registriert: Fr Okt 26, 2012 8:39 am

Re: Eigene Programmbibliothek zur Laufzeit laden

Beitrag von Glocke » Mi Jan 09, 2013 10:39 am

Nachtrag: Ich hab meinen github username geändert:

https://github.com/cgloeckner/sharedclasses

LG

Benutzeravatar
Xin
nur zu Besuch hier
Beiträge: 8862
Registriert: Fr Jul 04, 2008 11:10 pm
Wohnort: /home/xin
Kontaktdaten:

Re: Eigene Programmbibliothek zur Laufzeit laden

Beitrag von Xin » Mi Jan 09, 2013 11:29 am

Ich stehe ja mehr auf das ZIP Archiv... jetzt muss ich fat-lobyte wieder wegen dem GIT-Tutorial nerven. :->
Merke: Wer Ordnung hellt ist nicht zwangsläufig eine Leuchte.

Ich beantworte keine generellen Programmierfragen per PN oder Mail. Dafür ist das Forum da.

Glocke
Beiträge: 332
Registriert: Fr Okt 26, 2012 8:39 am

Re: Eigene Programmbibliothek zur Laufzeit laden

Beitrag von Glocke » Mi Jan 09, 2013 12:22 pm

Xin hat geschrieben:Ich habe das jetzt mit Windows und Linux nachvollzogen.
Ich hab es mal mit Wine probiert und musste ein paar Dinge ändern, z.B.

Code: Alles auswählen

#ifdef _WIN32
    #include <windows.h>
#else
    #include <dlfcn.h>
#endif
Zusätzlich zur build.sh hab ich noch eine build.bat geschrieben, die genauso zu bedienen ist und (basierend auf MinGW) für Win32 compiliert. (Ich hab eine Zusatzzeile drinnen, weil das mit dem Umgebungsvariablen bei mir nicht dauerhaft gespeichert wird.)

Code siehe GitHub ^_^

LG Glocke

Benutzeravatar
Xin
nur zu Besuch hier
Beiträge: 8862
Registriert: Fr Jul 04, 2008 11:10 pm
Wohnort: /home/xin
Kontaktdaten:

Re: Eigene Programmbibliothek zur Laufzeit laden

Beitrag von Xin » Mi Jan 09, 2013 1:07 pm

Glocke hat geschrieben:
Xin hat geschrieben:Ich habe das jetzt mit Windows und Linux nachvollzogen.
Ich hab es mal mit Wine probiert und musste ein paar Dinge ändern, z.B.

Code: Alles auswählen

#ifdef _WIN32
    #include <windows.h>
#else
    #include <dlfcn.h>
#endif
LG Glocke
Hmm... dlopen wird von Windows unterstützt!?
Suppi... ich habe eine Klasse geschrieben, die das unter Linux mit dlopen macht und unter Windows mit Windows-Bordmitteln. *grummel*
Merke: Wer Ordnung hellt ist nicht zwangsläufig eine Leuchte.

Ich beantworte keine generellen Programmierfragen per PN oder Mail. Dafür ist das Forum da.

Glocke
Beiträge: 332
Registriert: Fr Okt 26, 2012 8:39 am

Re: Eigene Programmbibliothek zur Laufzeit laden

Beitrag von Glocke » Mi Jan 09, 2013 1:12 pm

Xin hat geschrieben:Hmm... dlopen wird von Windows unterstützt!?
Bei mir meckerte der Compiler, die Include-Datei (die ich für dlopen brauche) nicht zu finden.
Xin hat geschrieben:Suppi... ich habe eine Klasse geschrieben, die das unter Linux mit dlopen macht und unter Windows mit Windows-Bordmitteln. *grummel*
Naja in dem Fall wäre doch die Verwendung der Windows-Bordmittel am geeignetsten oder sehe ich das falsch? Ich hatte mich dabei im Wikipedia-Artikel http://en.wikipedia.org/wiki/Dynamic_loading#Summary orientiert.

LG Glocke

Glocke
Beiträge: 332
Registriert: Fr Okt 26, 2012 8:39 am

Re: Eigene Programmbibliothek zur Laufzeit laden

Beitrag von Glocke » So Jan 13, 2013 9:32 am

Moin,
Getter und Setter als Wrapper-Methoden für Membervariablen:
Bisher muss ich die Membervariablen in der Wrapper-Klasse durch Getter und Setter ansprechen, die dann auf das interne data-Member (was die eigentliche Instanz enthält) zugreifen. Ich kann LibraryWrapper<T> aber nicht von T ableiten. Dann bekäme die Wrapper-Klasse zwar direkt die Membervariablen und ich könnte mir die Getter und Setter sparen, allerdings weiß ich noch nicht, wie ich dann den Konstruktor richtig aufrufe. Das mit der wrapper-Funktion create_xy erstellte Objekt darf ich nicht in this speichern.

Geht das überhaupt, was ich vor habe?

Mehrere Konstruktoren:
Dabei wird statt "create_Demo" (Standardkonstruktor) einfach der Parameter rangehangen, um einen - für das Laden mit dlsym - eindeutigen Funktionsnamen zu haben; z.B. create_Demo_int_int für einen Konstruktor (für die Klasse Demo), der 2 int als Parameter erhält.
Dann müssen nur noch die Konstruktoren von WrappedDemo implementiert werden, so dass sie den Oberklassekonstruktor aufrufen (der lädt nur noch die Shared Lib sofern nötig) und dann muss (im Wrapped-Konstruktor) die entsprechende Funktion geladen, der Funktionszeiger "zurechtgecastet" und die Funktion aufgerufen werden.
Der Punkt ist noch etwas hässlich :-S

Hat da jemand einen Ansatz für mich? :P

Ich komme an beiden Stellen nicht weiter :( Mein Problem ist, dass wenn ich so im großen Stil Klassen-Wrapper für eine SharedLib machen will, das aufgrund der casting-Syntax recht umständlich und langwierig wird.

LG Glocke

Antworten