Hallo nochmal,
eine andere Sache beschäftigt mich auch noch. Und zwar möchte ich einen Serverprogramm schreiben, bei dem es möglich ist zur Laufzeit Funktionalität hinzu zu fügen. Sprich also Plugins, wie bei z.B. Apache.
Dazu wird die Funktion dlopen genommen. DL steht wohl für dynamisches Laden.
Leider ist im Netz irgendwie zu diesem Thema überhaupt nichts zu finden. Und auch im Standartwerk von Stevens/Rago wird nur der Name der Funktion erwähnt. Kennt jemand von Euch eine Quelle, wo beschrieben ist, wie man da am besten vorgeht?
Gruss Christian
Doku und Beispiele zu dlopen
Doku und Beispiele zu dlopen
Zuletzt geändert von Columbus am 07.11.2007 23:34:52, insgesamt 1-mal geändert.
Die größten Kritiker der Elche,
waren früher selber welche.
F.W. Bernstein
waren früher selber welche.
F.W. Bernstein
-
- Beiträge: 3472
- Registriert: 30.11.2005 10:32:22
- Lizenz eigener Beiträge: MIT Lizenz
- Wohnort: Wald
Ich würde mitanfangen
Code: Alles auswählen
man dlopen
Wie man das aufruft ist mir ja klar, und welche Funktionen damit im Zusammenhang stehen. Was ich suche sind wie oben geschrieben: "Beispiele"
edit: okay ich habe auch Doku geschrieben, aber ich meine damit, wie man das am besten einsetzt. Erzeuge ich dafür einen Thread, der überwacht, ob ein Modul eingelinkt wird? Wie gestalte ich so ein Modul, es ist ja auch eine Bibliothek, aber ich brauche ja sowas wie ein gemeinsames Interface. Wird das als Stub implemntiert? Einfach keinen Plan!!!????
edit: okay ich habe auch Doku geschrieben, aber ich meine damit, wie man das am besten einsetzt. Erzeuge ich dafür einen Thread, der überwacht, ob ein Modul eingelinkt wird? Wie gestalte ich so ein Modul, es ist ja auch eine Bibliothek, aber ich brauche ja sowas wie ein gemeinsames Interface. Wird das als Stub implemntiert? Einfach keinen Plan!!!????
Die größten Kritiker der Elche,
waren früher selber welche.
F.W. Bernstein
waren früher selber welche.
F.W. Bernstein
ja, der Name des Entrypoints sollte dem aufrufenden Programm auch bekannt sein. In C++ Programmen wird von diesem Entrypoint oft ein Pointer auf ein Objekt zurückgeliefert. Damit das aufrufende Programm damit etwas anfangen kann, muß dieses aber auch hier, über das Interface dieser Klasse Bescheid wissen.Columbus hat geschrieben: Wie gestalte ich so ein Modul, es ist ja auch eine Bibliothek, aber ich brauche ja sowas wie ein gemeinsames Interface. Wird das als Stub implemntiert? Einfach keinen Plan!!!????
Daher werden meistens die Entrypoints, bzw gemeinsame ( abstrakte) Basisclassen (Interfaces) in Headerdateien deklariert, die sowohl vom aufrufenden Programm, als auch vom Modul includiert werden.
Gruß
gms
hi,
ein Beispiel aus dem wirklichen Leben: weil mir der Apache viel zu
kompliziert ist, hab' ich mir den bozohttpd aufgemotzt. Das Ergebnis
ist ein httpd, der ein CGI-Script als Plugin nachladen kann, ohne
neu zu starten.
Ein Plugin ist jeweils eine C-Funktion, aus der mit "gcc -fpic -shared"
ein shared object gemacht wird. Diese liegen alle in einem Verzeichnis.
Wenn der httpd ein SIGUSR1 bekommt, liest er das Verzeichnis und
lädt Plugins, die sich geändert haben mit dlopen(). Gleichzeitig wird
eine Liste aufgebaut
dlhandle ist das Ergebnis von dlopen(), die union enthält den Zeiger auf
die Funktion und ist nur dazu da, damit der gcc nicht meckert (Geht das
nicht eleganter?). script ist der Dateiname, aber "zufällig" auch der Name
der Funktion und des CGI-Scripts. Ein http-Request "/cgi-bin/foo?bar" führt
so zum Aufruf foo ("bar");
Dieses Beispiel ist natürlich besonders einfach, weil die Schnittstelle für
neue Plugins immer der http-Request ist. Wenn es mehrere verschiedene
Schnittstellen gibt, könnte man evt. mehrere "typedef cgi_fp()" benutzen,
die union ist ja eh' schon drin.
Das SIGUSER zum Nachladen kann man wohl auch durch inotify ersetzen,
dann geht's wirklich dynamisch.
Hoffentlich war das jetzt nicht völlig unverständlich.
ein Beispiel aus dem wirklichen Leben: weil mir der Apache viel zu
kompliziert ist, hab' ich mir den bozohttpd aufgemotzt. Das Ergebnis
ist ein httpd, der ein CGI-Script als Plugin nachladen kann, ohne
neu zu starten.
Ein Plugin ist jeweils eine C-Funktion, aus der mit "gcc -fpic -shared"
ein shared object gemacht wird. Diese liegen alle in einem Verzeichnis.
Wenn der httpd ein SIGUSR1 bekommt, liest er das Verzeichnis und
lädt Plugins, die sich geändert haben mit dlopen(). Gleichzeitig wird
eine Liste aufgebaut
Code: Alles auswählen
typedef int cgi_fp (const char *);
typedef struct cgi_st {
const char *script;
void *dlhandle;
union {
cgi_fp *f;
void *v;
} function;
time_t mtime; // mtime von plugin.so
int status; // Listenelement ist gültig/gelöscht/...
char *dlerr; // strdup (dlerror ())
struct cgi_st *next;
} cgi_st;
die Funktion und ist nur dazu da, damit der gcc nicht meckert (Geht das
nicht eleganter?). script ist der Dateiname, aber "zufällig" auch der Name
der Funktion und des CGI-Scripts. Ein http-Request "/cgi-bin/foo?bar" führt
so zum Aufruf foo ("bar");
Dieses Beispiel ist natürlich besonders einfach, weil die Schnittstelle für
neue Plugins immer der http-Request ist. Wenn es mehrere verschiedene
Schnittstellen gibt, könnte man evt. mehrere "typedef cgi_fp()" benutzen,
die union ist ja eh' schon drin.
Das SIGUSER zum Nachladen kann man wohl auch durch inotify ersetzen,
dann geht's wirklich dynamisch.
Hoffentlich war das jetzt nicht völlig unverständlich.
Beware of programmers who carry screwdrivers.