Hallo,
ich habe da eine Problemstellung, bei der ich für ein paar Anregungen
dankbar wäre.
Ich habe mehrere eigenständige SW-Module, die dafür gedacht sind, sowohl
von der Komandozeile, als auch mit einem GUI-Frontend aufgerufen zu
werden. Als Schnittstelle dient dabei eine Funktion, der ich die
Paramter (entweder die kopierten CL-Parameter, oder eben von der GUI
zusammengestellt) als vector<string> übergebe.
Jetzt hat zwar jedes Modul diese einheitlich definierte Schnittstelle,
aber in der Regel unterschiedliche Parameter.
Damit ich bei Hinzufügen/Ändern eines Moduls nicht jedes Mal die
Aufrufumgebung anpassen muss, ist mein Plan, dass jedes Modul über eine
weitere Funktion seine Parameter bekannt machen kann. Diese Funktion
soll eine Liste mit Descriptor-Objekten der möglichen Parameter liefen.
Ein solches Objekt z.B. folgende Informationen beinhalten:
- CL-Bezeichnung (z.B. -f für einen Dateinamen)
- Eine Kurzbeschreibung
- Ggf. eine ausführliche Beschreibung
- Den Typ (String, Int, Bool, ...)
- Default-Werte
- Für z.B. integer: Bereichs-Einschränkungen oder einzelne vorgegebene
Werte
- Eine Liste auswählbarer Werte, die z.B. in einer GUI in einem
Pull-Down menü erscheinen)
- Informationen welche Optionen sich gegenseitig ausschließen (Stichwort
Radio-button). Dafür könnte man ja z.B. Objekte zu einer Gruppe
zusammenfassen.
- ...
Ich suche jetzt nach eleganten Wegen eine solche Descriptor-Klasse
aufzubauen. Eventuell wäre es auch sinnvoll für jeden Parameter-Typ eine
eigene Klasse zu definieren und der gemeinsamen Basisklasse eine Funtion
zu verpassen, mit der sich der Typ abfragen lässt (Ich denke da an sowas
wie Qts QVariant).
Für kreative Vorschläge bin ich dankbar und offen.
Gruß
Hallo Philip,
Philip K. schrieb:> Ich habe mehrere eigenständige SW-Module, die dafür gedacht sind, sowohl> von der Komandozeile, als auch mit einem GUI-Frontend aufgerufen zu> werden. Als Schnittstelle dient dabei eine Funktion, der ich die> Paramter (entweder die kopierten CL-Parameter, oder eben von der GUI> zusammengestellt) als vector<string> übergebe.>> Jetzt hat zwar jedes Modul diese einheitlich definierte Schnittstelle,> aber in der Regel unterschiedliche Parameter.> Damit ich bei Hinzufügen/Ändern eines Moduls nicht jedes Mal die> Aufrufumgebung anpassen muss, ist mein Plan, dass jedes Modul über eine> weitere Funktion seine Parameter bekannt machen kann.> [...]> Für kreative Vorschläge bin ich dankbar und offen.
Da gibt es auch Boost.Program_options oder auch sowas:
Das ist jetzt auf die Schnelle gehackt und kann auch viel schöner
gemacht werden. Natürlich kann man da statische help()-Methoden
hinzufügen und die Module seriell in einen Array-Container packen, mit
Templates arbyten oder ... Aber der eigentliche Trick ist, daß jedes
Modul sich die für das Modul nötigen und nützlichen Parameter
herauspickt und den Rest ignoriert.
HTH,
Karl
Hallo Karl,
Boost sollte ich mir wohl insgesammt mal näher ansehen, da scheints
viele nützliche Dinge zu geben.
Zu Deinem Beispiel - Danke für die Mühe, aber das ist nicht ganz das was
ich meinte.
Ich versuchs nochmal anders:
- Ein Programm (GUI, da wirds anschaulicher) wird mit einer
erweiterbaren Anzahl von Modulen kompiliert. Diese Module haben eine
einheitliche Aufrufschnittstelle aber unterschiedliche Parameter.
- Beim Programmstart wird von jedem Modul eine Instanz erstellt und ein
paar Basisinformationen (Modulname etc.) abgeholt und in eine Liste
(Combobox), dem Anwender zur Auswahl gestellt.
- Der Anwender wählt ein Modul aus und die Basisapplikation holt sich
daraufhin von diesem Modul die verfügbaren Parameter und trägt sie in
ein Config-Fenster ein.
- Der Anwender ändert ggf. Optionen und klickt auf einen Start-Button.
- Die Basisapplikation überreicht dem Modul die aktuellen Parameter als
Strings über die einheitliche Aufrufschnittstelle und startet damit
einen Ablauf.
Gruß
Philip
Karl Käfer schrieb:> HTH,
??? :-)
Philip K. schrieb:> - Der Anwender wählt ein Modul aus und die Basisapplikation holt sich> daraufhin von diesem Modul die verfügbaren Parameter und trägt sie in> ein Config-Fenster ein.
Sind die auswählbaren Parameter immer endlich (und ggf. auf eine mäßige
Größe beschränkt), oder kommen auch welche vor in der Art "ganze Zahl"
oder Gleitkommazahl zwischen -4.21 und +10.987"?
Beliebige Dateinamen?
Dann wäre "holt sich daraufhin von diesem Modul die verfügbaren
Parameter" natürlich ganz anders zu interpretieren.
Ich habe in einem C++-Kurs mal für ein Art modularen Synthesizer mit
flexiblen Modulen gearbeitet, die sich beim Pogramm registrieren
konnten, damit die GUI bzw. das Konsolenprogramm was damit anfangen
konnten.
Als Beispiel der Anfang (die Includes mal weggelassen) eines solchen
Moduls zur Hallerzeugung, jedes Modul registrierte seine Ein- und
Ausgänge, damit die Module in der GUI miteinander verdrahtet und damit
dann ein Ton erzeugt werden konnte:
1
//Statisches Objekt von der eigenen Klasse wird initialisiert, dient der Modul-Registrierung
Klaus Wachtler schrieb:> Sind die auswählbaren Parameter immer endlich (und ggf. auf eine mäßige> Größe beschränkt), oder kommen auch welche vor in der Art "ganze Zahl"> oder Gleitkommazahl zwischen -4.21 und +10.987"?
Das sollte schon möglich sein. Deshalb dachte ich mir ja, dass ich eine
Deskriptorklasse für jeden möglichen Datentyp (string, int float, bool,
...)implementiere, die u.a. Auskunft darüber gibt, welche Werte erlaubt
sind.