Methode aus String aufrufen (dynamisch)

Doomt

Mitglied
Guten Tag Allen ;)

Für den Titel ist mir nichts besseres eingefallen.

Ich würde gerne einen dynamischen Methoden aufruf in mein C++ Programm einbauen.
Ich mein damit, dass der User eine Text eingabe macht, zB.: "addieren" und das Programm
ruft die Methode addieren auf, allerdings meine ich nicht eine "if/else" oder "switch"
überprüfung, sondern eine Variante den String direkt als Methode aufzurufen.

Mein Gedanke dabei:
Dass ich zum Beispiel bei einem Taschenrechner eingebe: "addieren"
und das Programm entweder addiert, oder wenn addieren nicht vorhanden ist
einen Fehler ausgibt, dass die Funktion nicht gefunden wurde.
(Ich stelle mir vor dass es eine angenehme Variante zur anbindung von
Erweiterungen wäre, ohne if/else struktur oder fixe Methoden namen, usw...)

Bisherige Tipps von ComFreek (ich hoffe ich darf dich hier nennen :p ):

zuerst einenicht ganz dynamische Variante aber theoretisch könnte man bei den Erweiterungen eine Methode aufrufen welche die Funktionen in die Map einträgt.
ComFreek hat gesagt.:
das was du vor hast, würde ich mit einer Look-Up-Map lösen.
Weißt du was eine Map (in der Informatik :p) ist? Du weist jeweils einem einzigartigen Schlüssel einen Wert zu.

Der Schlüssel wäre in deinem Fall der Methodenname und der Wert der Funktionspointer zu der Funktion.

Erstmal bräuchtest (damit's angenehmer wird) du ein typedef:
C++:
typedef [Funktionspointer-Typ] MyPointer;
Wobei das in den Klammern deinen Typ deiner Funktionen darstellt.

Danach eine Map definieren:
C++:
std::map<std::string, MyPointer>

Diese füllen und jeweils Werte entnehmen

Und die 2te Variante muss erst ausprobiert werden, hier gibt es keine gewährleistung dass sie so funktioniert :D

ComFreek hat gesagt.:
Ich könnte mir noch was mit GetProcAddress() vorstellen.

So in etwa folgendes, keine Ahnung, ob's funktioniert:
C++:
typedef void (*MY_FUNC_TYPE)(const char*) ;
 
void helloWorld(const char *str) {
  MessageBox(NULL, str, "", 0);
}
 
HMODULE thisModule = GetModuleHandle(NULL);
MY_FUNC_TYPE helloFunc = (MY_FUNC_TYPE) GetProcAddress(thisModule, "helloWorld");
if (helloFunc) {
  helloFunc();
}
else {
  MessageBox(NULL, "Failed", "", 0);
}

Ich wurde gefragt die Frage im Forum zu posten, damit alle mitreden können
(ehrlich gesagt wusste ich nicht nach was ich suchen sollte und nach 15 min erfolgloser Forum & Google Suche, da man mit dynamischen Methoden aufruf oder String und Methode nur andere Ergebnisse bekommt )

mfg,
Doomt
 
Hallo,
warum nutzt du nicht einfach die erste Methode? Die macht doch genau was du willst. Du kannst es auch per Array lösen, aber die Methode mit der Map ist eigentlich ganz geschickt. Die zweite Variante macht ja im Prinzip auch nichts anders, nur über Umwege.

Grüße,
Jennesta
 
Meine überlegung ist/war, ob es eine Variante gibt, wo ich nicht etwas statisch selber füllen muss um danach dynamisch zu sein.

Ich will damit, mein Wissen erweitern, ob die Varianten sinnvoll sind wegen Performance usw.. ist mir hier eigentlich egal.

Die Möglichkeiten wissen, erleichtert das finden einer Lösung meiner Meinung nach ;)

Die 1te Variante ist recht einfach und eigentlich auch dynamisch, aber es gibt immer mehr als nur einen Weg etwas zu machen.

Die 2te Variante ist wenn es so funktioniert schon wirklich dynamisch, man müsste nur kontrollfunktionien einbauen, dass nicht interne Funktionen, welche ien User nie selber aufrufen können sollte, hiermit aufgerufen werden. (Wie weit das mit Erweiterungen kompatibel ist, muss auch erst geprüft werden )
 
Hallo,

das erinnert mich an die Reflection-Möglichkeiten die ich aus Java kenne. Willst du auf etwas in der Art hinaus?

Ich würde dann wahrscheinlich wie Methode 1 dann arbeiten mir nur zusätzlich vielleicht ein Macro überlegen, dass "Meta-Code" zu jeder Funktion automatisch hinzufügt mit dessen Hilfe dann die entsprechende Methode in die Look-Up Map aufgenommen wird. Zum Beispiel ähnlich den Unit-Test Framework Macros des Visual Studios von Mircosoft.

Gruß,
Wolf
 
Hmm ich würd sagen es geht in die richtung.

Dann wird Methode nr 1 eh schon die Antwort sein.
Werd erledigt anhackeln.
Nur falls es wer sucht, ist es jetzt auch im Forum zu finden und nicht nur in meinem Posteingang :D
 
Hallo Doomt,

ja, du darfst mich gerne zitieren.

dass nicht interne Funktionen, welche ien User nie selber aufrufen können sollte, hiermit aufgerufen werden
Genau, das ist sehr wichtig! Evtl. hier mit Präfixen bei Funktionsnamen arbeiten. Um den Präfix leicht editierbar zu halten, würde ich ein einfaches Macro empfehlen.

Sowas in der Art:
C++:
#define CALC_FUNC(X) PREFIX_X

int CALC_FUNC(multiply)(int a, int b) {
  return a * b;
}

Doomt (aus PN) hat gesagt.:
Typ der Funktion meinst du jetzt den Rückgabe Wert?
Nein, der Typ der Funktion ist ein Typ, der die Funktion an sich beschreibt. Auch "Function pointers" genannt, einfach mal googeln ;)

Ich weiß nicht wie dynamisch du es halten möchtest, aber ein professionellerer Ansatz wäre folgender:

Dein Rechner unterstützt sogenannte Plugins, welche Funktionen in arithmetischen Operationen unterstützen.
Ein Plugin kann eine oder mehrere Funktionen bereitstellen.

Plugins werden in einem speziellen Ordner gesammelt oder auf eine andere spezifische Weise registriert.
Dein Programm lädt nun beim Start alle Plugin-Bibliotheken (DLLs oder SOs). Jedes Plugin definiert eine getFunctionList()-Funktion (den Pointer auf diese bekommst du via GetProcAddress()), welche die verfügbaren Funktionen (und Referenzen) zurückliefert.
 
Zurück