Guten Morgen,
folgendes Problem: Ich habe eine Textdatei, in der u.a. ein
Funktionsname steht. Die Datei wird geparst und dann soll die Funktion
aufgerufen werden. Programmiert wird in C++.
1
// prototyp
2
intaddiere(inta,intb);
3
4
.
5
.
6
.
7
8
intmain()
9
{
10
charFunktionsname[20];
11
12
ParseTextDatei(&Funktionsname);
13
14
// in der Textdatei steht jetzt die Funktion addiere, die aufgerufen werden soll
15
16
return0;
17
}
18
19
20
21
22
// implementierung
23
intaddiere(inta,intb)
24
{
25
return(a+b);
26
}
Meine Idee ist, ein Array von Funktionspointern anzulegen, da das aber
später über 400 Funktionen werden können ist das doch sehr umfangreich.
Gibt da etwas besseres?
Danke für Hinweise.
Gruß Mike
Das klingt so als würdest du dir eine art scriptsprache bauen wollen.
Was du suchst nennt sich eval() ist aber aus guten Gründen nicht so
einfach in C++ möglich.
Der richtige Weg wäre es einen richtigen Tokenizer zu implementieren.
Und ja wenn man das noch nie gemacht hat muss man hierzu einiges lesen
etc. Für nen schnellschuß ist daher die variante einer hashmap string=>
funktion das einfachste...besonderst wenn du es nur einmalig machst
TestX schrieb:> Und ja wenn man das noch nie gemacht hat muss man hierzu einiges lesen
Daran soll es nicht scheitern und mir geht es auch nicht darum, dass ihr
mir den fertigen Code hier reinschreibt. Ich suche einfach eine Methode
um mein Problem zu lösen und mit meinen bisherigen Erfahrungen kam ich
nur auf die Idee mit der Tabelle, wobei ich das auch noch nicht
umgesetzt habe.
Walter T. schrieb:> Du willst also einen Interpreter bauen?
Nicht wirklich. Wir haben eine GUI, die mit C++ programmiert wurde und
diese soll nun erweitert werden. Diese Erweiterung soll, wie oben
beschrieben, eine Funktion anhand eines Strings aufrufen.
Ich habe aber gerade gesehen, dass mit LUA, Python oder was auch immer
in C++ einbinden kann. Ist das aber nicht viel mehr Aufwand als eine
Tabelle anzulegen? Oder gibts hier rieseige Vorteile, die ich gerade
noch nicht sehe?
Mike schrieb:> Ist das aber nicht viel mehr Aufwand als eine Tabelle anzulegen? Oder> gibts hier rieseige Vorteile, die ich gerade noch nicht sehe?
Du hast bisher überhaupt noch nichts über den Anwendungszweck und
weitere Inhalte dieser Beschreibungsdatei erwähnt. Ich vermute, dass in
der Datei auch noch Aufrufparameter der betreffenden Funktion stehen
sollen. Wie sieht es mit der Auswertung oder Darstellung der
Rückgabewerte aus? Dann benötigt Ihr vermutlich eine Art
Variablenkonzept. Und was ist mit den Typen der Parameter? Und
Polymorphie?
Je nachdem, wie diese (und noch etliche andere Aspekte) berücksichtigt
werden müssen, hat dies gewaltige Auswirkungen darauf, ob eine einfache
Tabelle ausreicht, ein eigener Parser sinnvoll wäre oder doch eher auf
eine Skriptsprache (mit C++-Interface) vorzuziehen wäre. Außer für sehr
triviale Dinge würde ich heutzutage nicht versuchen, das Rad neu zu
erfinden, sondern auf bestehenden Lösungen (Skriptsprache)
zurückgreifen, auch wenn sie manchmal eher aufgebläht erscheinen.
Es sind alles void Funktionen und es werden nur diverse Dinger
angetriggert. Es werden auch keine Parameter übergeben, von daher sollte
in einem ersten Ansatz die Tabelle reichen. Aber wie das so ist, werden
in der Zukunft sehr wahrscheinlich noch weitere Anforderungen kommen.
Ich gebe mich nun mal an den Ansatz mit der Tabelle und werde mal 5
Funktionen speichern. Danach versuche ich mal den Ansatz über die
Scriptsptrache. So habei ich beides mal gemacht.
Mike schrieb:> Danach versuche ich mal den Ansatz über die> Scriptsptrache
Überlege mal, was du da ins Script reinschreiben willst: eine
case-Anweisung mit 400 Funktionsnamen und den dazugehörigen
Funktionsaufrufen. Gewonnen gegenüber der Tabelle ist damit garnichts,
es ist nur unnötig verkompliziert.
Was anderes ist es, die Script-Interpreter-Source als Vorlage zu
benutzen, aber das ist auch Overkill für so eine einfache Zuordnung.
Georg
Mike schrieb:> Meine Idee ist, ein Array von Funktionspointern anzulegen, da das aber> später über 400 Funktionen werden können
400 Schlüsselwörter?
Da würde ich mir ganz schwer eine Systematik und eine kleine Syntax
überlegen, wie ich diese Anzahl runterbringen kann. Das its zwar
momentan dann für dich mehr Aufwand aber deine Benutzer werden es dir
auf lange Sicht danken.
Oh, und rangehen würde ich dann mit Compiler-Bau Tools.
Denn der Appetit wächst mit dem Essen. Irgendwann soll in deiner 'Script
Sprache' dann nämlich auch gerechnet werden können, Variablen werden
gewünscht, Zugriff auf Werte des zu steuernden Systems die in Ausdrücken
benutzt werden können, etc. etc. Und dann siehst du mit deiner
Funktionstabelle (die funktionieren wird und die momentan sicherlich das
einfachste ist) dann ziemlich alt aus.
Mike schrieb:> folgendes Problem: Ich habe eine Textdatei, in der u.a. ein> Funktionsname steht. Die Datei wird geparst und dann soll die Funktion> aufgerufen werden. Programmiert wird in C++.
Es gibt einen Zuordnung von Funktionsname (Zeichenkette) auf
Funktionspointer. Es gibt eine Liste solcher Zuordnungen.
Die Aufgabe ist es, für einen gegebenen Funktionsnamen (Zeichenkette)
den zugehörigen Funktionspointer zurückzuliefern.
Das ist das Problem? Ist das Parsen das Problem?
> Meine Idee ist, ein Array von Funktionspointern anzulegen, da das aber> später über 400 Funktionen werden können ist das doch sehr umfangreich.
Wenn es 400 unterschiedliche Funktionen gibt, wirst du da kaum drum
herum kommen, oder gibt es eine Herleitung für die 400 Funktionen, die
die Menge reduziert?
> Gibt da etwas besseres?
Kommt drauf an. Ich habe die Problematik wohl nicht wirklich verstanden.
;-)
S. J. schrieb:> Wenn es 400 unterschiedliche Funktionen gibt, wirst du da kaum drum> herum kommen, oder gibt es eine Herleitung für die 400 Funktionen, die> die Menge reduziert?
Die Anzahl kann ich nicht reduzieren, da diese Funktionen bereits
vorgegeben sind.
S. J. schrieb:> Die Aufgabe ist es, für einen gegebenen Funktionsnamen (Zeichenkette)> den zugehörigen Funktionspointer zurückzuliefern.
Genau, "mehr" nicht.
400 ist doch "Peanuts" (ich sehe hier das Problem nicht???)
wenns schnell gehen soll, würde ich a HashTable machen, oder sowas..
(oder einfach meine vorschlag NICHT ignorieren
Beitrag "Re: Funktion über String aufrufen" dort kann man wohl
auch benutzerdefinierte funktionen hinzufügen..)
Gibt es in der STL fertig als std::map.
Daraus macht man sich eine Zuordnung von String auf die Funktion bzw.
einen Zeiger darauf.
Man kann sich aber auch eine eigene Klasse definieren, die jeweils eine
Methode enthält (deine auszuführende Funktion) und selbst weiß, wie sie
heißt.
Davon schmeisst man meinetwegen 400 in ein std::set und kann sie darin
anhand des Namens finden.
Das ist etwas mehr in Richtung OOP als die schnöde Map mit
Funktionszeigern.
Robert L. schrieb:> oder einfach meine vorschlag NICHT ignorieren
keine Sorge, habe ich schon zur Kenntnis genommen. Danke.
Klaus W. schrieb:> Gibt es in der STL fertig als std::map.
Ok, schaue ich mir auch mal an
Mike schrieb:>> Die Aufgabe ist es, für einen gegebenen Funktionsnamen (Zeichenkette)>> den zugehörigen Funktionspointer zurückzuliefern.>> Genau, "mehr" nicht.
Dann (1) iterierst du über deine Liste/Vector/Array mit der Input
Zeichenkette solange, bist du die passende Zuordnung gefunden hast.
Wenn es schneller gehen soll nimmst du (2) eine std::map. Bessere
Performance bietet (3) std::unordered_map (C++11) oder das Boost
Equivalent. Wenn es Super-Speed-schnell gehen soll, baust du dir eine
(4) State Machine (Overkill!)
Ich würde (1) nehmen (kann man später optimieren) und erstmal gucken was
denn ansonsten für Probleme auf dich zukommen. ;-)
Mike schrieb:> Diese Erweiterung soll, wie oben> beschrieben, eine Funktion anhand eines Strings aufrufen.
Dann bleibt natürlich die Frage: Wie oft? Und wie oft ändert das sich?
Walter T. schrieb:> Dann bleibt natürlich die Frage: Wie oft? Und wie oft ändert das sich?
Sehr sehr langsam. Der User kann sich Seiten generieren und nur, wenn er
sich die Seite umgestaltet werden andere oder neue Funktionen
aufgerufen.
Mike schrieb:> Sehr sehr langsam
Dann spricht ja nichts gegen eine einfache Tabelle mit Funktionspointer
und -Namensstring, wenn diese nur selten durchsucht werden muß. Das
Ergebnis kann ja beliebig zwischengespeichert werden.
Warum nicht einfach einen lua Interpreter in das Programm einbetten.
Jede Nutzer-Funktion die es gibt dann einfach beim lua registrieren.
Dann kann quasi beliebiger Lua code ausgeführt werden, der Anwender ist
also später nicht auf den reinen Funktionsaufruf beschränkt. (Die
Anforderung kommt früher oder später sowieso)
Wir machen das bei unseren Gateways auch so.
Andreas M. schrieb:> Warum nicht
KISS. Er sollte das Ganze kapseln (register, call, ...) und fertig.
Details eventuell irgendwann notwendiger Erweiterungen sind zum
jetzigen Zeitpunkt sowieso unbekannt.
Mike schrieb:> Klaus W. schrieb:>> Gibt es in der STL fertig als std::map.>> Ok, schaue ich mir auch mal an
Das sieht lauffähig etwa aus wie in t.cpp.
Weil es etwas langweilig ist, kann man ab C++11 das auch mit
Lamdafunktionen machen, dann braucht man nicht die Funktionen explizit
hinschreiben und ihre Adresse übergeben, sondern definiert sie nebenbei
beim Einfügen in die std::map<>.
Mike schrieb:> folgendes Problem: Ich habe eine Textdatei, in der u.a. ein> Funktionsname steht. Die Datei wird geparst und dann soll die Funktion> aufgerufen werden. Programmiert wird in C++.
Falsche Wahl. Wenn man die Eigenschaften eine Interpretersprache haben
wil, dann benutzt man einfach eine Interpreterprache. Capisce?
Wenn der Kulturschock nicht gar so groß sein soll, würde sich vielleicht
C# anbieten. Denn C# kann notfalls sogar wirklich "interpretieren".
Tatsächlich allerdings kann es was noch wesentlich besseres:
JIT-kompilieren.
D.h.: Der Perfomance-Nachteil gegenüber C++ ist zwar vorhanden, teils
sogar sehr störend ausgeprägt, aber zumindest der kompilierte
"Scriptcode" wird wesentlich effizienter laufen als alle anderen
Konstrukte, die mit C++ machbar wären. Allein deshalb, weil der
"Scriptcode" im vollen Umfang von allen Optimierungen profitieren kann,
denen C# und .net teilhaftig wurde...
Klaus W. schrieb:> Weil es etwas langweilig ist, kann man ab C++11 das auch mit> Lamdafunktionen machen, dann braucht man nicht die Funktionen explizit> hinschreiben und ihre Adresse übergeben, sondern definiert sie nebenbei> beim Einfügen in die std::map<>.
Verzeih' bitte, aber Dein Beispiel "t_lambda.cpp" ist immer noch mit
Funktionszeigern (meineFunktion_t) unterwegs...
std::cout<<"which function do you want to call? -> ";
17
std::cin>>line;
18
// @todo check if $line is in %funcmap
19
funcmap[line]();
20
}
21
22
return0;
23
}
PS: Ich finde auch nicht, daß ein Programm seinen Benutzer auf bairisch
(fränkisch?) beschimpfen sollte. Usability-Untersuchungen haben gezeigt,
daß höfliche Programme vom Benutzer besser angenommen werden. ;-)
Klaus W. schrieb:> Das sieht lauffähig etwa aus wie in t.cpp.
Man koennte das noch mit etwas Codegenerierung kombinieren, so dass man
die Funktionen nicht selbst in die Tabelle eintragen muss.
Sobald es nennenswert komplizierter wird als in diesem Beispiel, kann
man sich damit aber eine unwartbare Katastrophe frickeln und sollte auf
etwas anderes umsteigen.
Grobe Skizze der Idee im Anhang.
Sheeva P. schrieb:> Verzeih' bitte, aber Dein Beispiel "t_lambda.cpp" ist immer noch mit> Funktionszeigern (meineFunktion_t) unterwegs...
Das kann man natürlich noch tausendfach variieren, meinetwegen auch
gerne mit std::function (dahinter vergirgt sich dann jeweils eine
generierte Klasse mit einer Methode, die - eine Adresse hat und darüber
aufgerufen wird).
Sheeva P. schrieb:> PS: Ich finde auch nicht, daß ein Programm seinen Benutzer auf bairisch> (fränkisch?) beschimpfen sollte. Usability-Untersuchungen haben gezeigt,> daß höfliche Programme vom Benutzer besser angenommen werden. ;-)
Daß mit bairisch finde ich jetzt beleidigend; mit fränkisch hast du
gerade noch die Kurve gekriegt.
Inwieweit solche Ausgaben wirklich beleidigend sind, liegt im Auge des
Angesprochenen. Bei Franken ist so etwas nicht unbedingt böse gemeint.
Du darfst es gerne durch irgendwelche Kuschelsprüche ersetzen, dem
Compiler wird es egal sein.
Sheeva P. schrieb:> Ich finde auch nicht, daß ein Programm seinen Benutzer auf bairisch> (fränkisch?) beschimpfen sollte.
Aber wenn das doch so im Lastenheft steht?
Klaus W. schrieb:> Das kann man natürlich noch tausendfach variieren, meinetwegen auch> gerne mit std::function (dahinter vergirgt sich dann jeweils eine> generierte Klasse mit einer Methode, die - eine Adresse hat und darüber> aufgerufen wird).
Die function-Objekte sind schon sehr praktisch und haben seit ihrer
Einführung in C++11 bei mir die Funktionszeiger praktisch vollständig
verdrängt.
Ihr Vorteil liegt eben darin, dass sie im Gegensatz zu Funktionszeigern
nicht nur freie Funktionen und Klassenmethoden, sondern auch Closures,
Funktionen mit vorbelegten Argumenten, Instanzmethoden (zusammen mit
einer Objektreferenz) u.v.m. darstellen können. Gerade letztere sind in
der objektorientierten Programmierung ziemlich wichtig.
Sheeva P. schrieb:> std::map< std::string, std::function<void(void)> > funcmap
Sooo... da muss jetzt nur noch eine Parameter-Übergabe mit rein:
Mike schrieb:> int addiere( int a, int b )> {> return ( a + b );> }
Und dann, nächste Woche, wenn die nächste Übungsaufgabe ansteht, müssen
Funktionsaufrufe noch geschachtelt werden können:
> print(addiere(2,2))
Übernächste Woche soll dann die "addiere"-funktion durch einen
infix-Operator '+' ersetzt werden.
Danach Punkt-vor-Strich, Klammerung, Variablen, ....
Walter T. schrieb:> Sheeva P. schrieb:>> Ich finde auch nicht, daß ein Programm seinen Benutzer auf bairisch>> (fränkisch?) beschimpfen sollte.>> Aber wenn das doch so im Lastenheft steht?
Dann kann man das immer noch im Pflichtenheft umschreiben ;-)
Yalu X. schrieb:> Die function-Objekte sind schon sehr praktisch und haben seit ihrer> Einführung in C++11 bei mir die Funktionszeiger praktisch vollständig> verdrängt.
Man sollte noch erwähnen, dass es auch einige (kleine) Nachteile gibt.
Die std::function Objekte sind recht groß und reservieren meistens
dynamisch Speicher. Außerdem sind die Aufrufe der gespeicherten
Funktionen etwas teurer weil ein virtual function call benötigt wird.
Auf dem PC ist das wenig relevant, auf eine µc wäre man mit normalen
function pointers vielleicht besser beraten.
Yalu X. schrieb:> Die function-Objekte sind schon sehr praktisch und haben seit ihrer> Einführung in C++11 bei mir die Funktionszeiger praktisch vollständig> verdrängt.
Die gibt es doch aber nicht erst seit C++11, oder? Den
Funktionsaufruf-Operator () kann man schon ziemlich lange überladen.
Klaus W. schrieb:> Sheeva P. schrieb:>> Verzeih' bitte, aber Dein Beispiel "t_lambda.cpp" ist immer noch mit>> Funktionszeigern (meineFunktion_t) unterwegs...>> Das kann man natürlich noch tausendfach variieren, meinetwegen auch> gerne mit std::function (dahinter vergirgt sich dann jeweils eine> generierte Klasse mit einer Methode, die - eine Adresse hat und darüber> aufgerufen wird).
std::function ist hier nur der Typ der Funktion für das Map-Template;
der eigentliche Lambda-Ausdruck ist jener Teil: "[...](...)->...{...}".
Dabei handelt es sich um anonyme, also unbenannte Funktionen, welche
zwar recht ähnlich wie ein Funktionszeiger arbeiten, aber eine bessere
Typsicherheit bieten und den Kontext (im "[...]"-Teil) mitnehmen können.
Guckstu: [1,2]
> Sheeva P. schrieb:>> PS: Ich finde auch nicht, daß ein Programm seinen Benutzer auf bairisch>> (fränkisch?) beschimpfen sollte. Usability-Untersuchungen haben gezeigt,>> daß höfliche Programme vom Benutzer besser angenommen werden. ;-)>> Daß mit bairisch finde ich jetzt beleidigend; mit fränkisch hast du> gerade noch die Kurve gekriegt.> Inwieweit solche Ausgaben wirklich beleidigend sind, liegt im Auge des> Angesprochenen. Bei Franken ist so etwas nicht unbedingt böse gemeint.> Du darfst es gerne durch irgendwelche Kuschelsprüche ersetzen, dem> Compiler wird es egal sein.
Entschuldige, ich wollte Dich nicht beleidigen und kenne mich mit dem
kulturellen Kontext fränkischer Umgangsformen auch nicht so gut aus.
[1] http://de.cppreference.com/w/cpp/language/lambda
[2] http://www.drdobbs.com/cpp/lambdas-in-c11/240168241
Mark B. schrieb:> Yalu X. schrieb:>> Die function-Objekte sind schon sehr praktisch und haben seit ihrer>> Einführung in C++11 bei mir die Funktionszeiger praktisch vollständig>> verdrängt.>> Die gibt es doch aber nicht erst seit C++11, oder? Den> Funktionsaufruf-Operator () kann man schon ziemlich lange überladen.
Das schon, aber die Klasse function und das zugehörige Header-File
functional wurden erst in C++11, zusammen mit der Lambda-Syntax
eingeführt. Vorher hat man sich etwas Entsprechendes entweder selber
zusammengestrickt, oder man hat die Boost-Bibliotheken Function,
Bind und Lambda benutzt, aber beides natürlich ohne die neue Syntax.
Sebastian V. schrieb:> Die std::function Objekte sind recht groß und reservieren meistens> dynamisch Speicher. Außerdem sind die Aufrufe der gespeicherten> Funktionen etwas teurer weil ein virtual function call benötigt wird.> Auf dem PC ist das wenig relevant, auf eine µc wäre man mit normalen> function pointers vielleicht besser beraten.
Das hat mich dann doch interessiert, und ich bin zu folgenden
Ergebnissen gekommen (Dateien im Anhang):
1
g++ -std=c++11 -O0 point.cpp -o point
2
g++ -std=c++11 -O0 main.cpp -o main
3
63336 main
4
46312 point
5
31152 main
6
22952 point
7
8
g++ -std=c++11 -O1 point.cpp -o point
9
g++ -std=c++11 -O1 main.cpp -o main
10
21512 main
11
20208 point
12
14760 main
13
14752 point
14
15
g++ -std=c++11 -O2 point.cpp -o point
16
g++ -std=c++11 -O2 main.cpp -o main
17
21544 main
18
20248 point
19
14752 main
20
14744 point
21
22
g++ -std=c++11 -O3 point.cpp -o point
23
g++ -std=c++11 -O3 main.cpp -o main
24
25528 main
25
20128 point
26
18848 main
27
14744 point
28
29
g++ -std=c++11 -Os point.cpp -o point
30
g++ -std=c++11 -Os main.cpp -o main
31
21432 main
32
15768 point
33
14720 main
34
10616 point
Spannend, daß -O{1,2,s} bei der main.cpp beinahe gleichauf liegen und
-O3 sogar ein deutlich größeres Kompilat erzeugt, während bei der
Version mit Funktionszeigern nur -Os so richtig was nutzt (g++ Ubuntu
4.9.1-16ubuntu6).
Mit Link Time Optimization liegen die beiden Varianten dann allerdings
wieder deutlich näher beieinander:
1
g++ -std=c++11 -O0 -flto point.cpp -o point
2
g++ -std=c++11 -O0 -flto main.cpp -o main
3
56176 main
4
39840 point
5
31152 main
6
22952 point
7
8
g++ -std=c++11 -O1 -flto point.cpp -o point
9
g++ -std=c++11 -O1 -flto main.cpp -o main
10
20720 main
11
19456 point
12
14752 main
13
14744 point
14
15
g++ -std=c++11 -O2 -flto point.cpp -o point
16
g++ -std=c++11 -O2 -flto main.cpp -o main
17
20704 main
18
19440 point
19
14744 main
20
14736 point
21
22
g++ -std=c++11 -O3 -flto point.cpp -o point
23
g++ -std=c++11 -O3 -flto main.cpp -o main
24
20704 main
25
19440 point
26
14744 main
27
14736 point
28
29
g++ -std=c++11 -Os -flto point.cpp -o point
30
g++ -std=c++11 -Os -flto main.cpp -o main
31
16496 main
32
15120 point
33
10624 main
34
10616 point
Nachtrag: könnte ein Moderator bitte die kleinere "compile.sh" löschen?
Lieben Dank.
[Mod: Hab's gelöscht]
THX!
Sheeva P. schrieb:>> Die std::function Objekte sind recht groß und reservieren meistens>> dynamisch Speicher. Außerdem sind die Aufrufe der gespeicherten>> Funktionen etwas teurer weil ein virtual function call benötigt wird.
Hier geht es nicht um Code-Größe.
>> Das hat mich dann doch interessiert, und ich bin zu folgenden> Ergebnissen gekommen (Dateien im Anhang):
Du hast Code-Größe gemessen.
In der Codegröße scheint das tatsächlich kaum Unterschied zu machen. Im
übrigen sind die Unterschiede zwischen deinen Beispielen größer als sie
sein müssen. In der Variante mit Function Pointers kann man weiterhin
Lambdas nutzen (sofern diese keine captures speichern). Der einzige
Unterschied wäre also nur den Typ der Map von std::function<void(void)>
auf void(*)(void) zu ändern.
sebastian schrieb:> Du hast Code-Größe gemessen.
Ja, für den Rest war ich zu faul, das ist für so kleine Schnipselchen
aber meistens ein ganz guter Anhaltspunkt. Hier offenbar nicht; der
Effekt bei der Optimierung ist zwar ähnlich, dafür hängt die
Funktionszeigerversion die Lambdaversion viel deutlicher ab:
Georg schrieb:> ine> case-Anweisung mit 400 Funktionsnamen und den dazugehörigen> Funktionsaufrufen.
Wenn man Python als Sprache verwendet braucht man keine case-Anweisung.
Man kann dort einen String direkt mit dem Befehl exec ausführen.
BTW es gibt auch noch eine ganz andere Variante:
Man könnte die aufzurufenden Funktionen in eine *.so (Windows: *.DLL)
packen und zur Laufzeit vom Hauptprogramm nachladen mit
dlopen()/dlclose() (Windows: LoadLibrary() o.s.ä.).
Dann kann man anhand des gewünschten Namens das zugehörige Symbol bauen
(wahrscheinlich _ davor) und mit dlsym() (Windows: GetProcAddr()
o.s.ä.).
Das liefert erinen Zeiger auf die Funktion, die man dann aufrufen kann.
Ist erstmal umständlicher, aber öffnet die Möglichkeit durch Austauch
der .so andere Funktionen laden zu können, ohne das Hauptprogramm ändern
zu müssen (z.B. für Anpassungen, die sich ein Kunde selbst bauen oder
anderweitig beschaffen kann -> Plugin).
Mike schrieb:> Wir haben eine GUI, die mit C++ programmiert wurde und> diese soll nun erweitert werden.
Hallo,
ich gehe mal stark davon aus, dass du dann Qt nutzt?!?
Qt kann das nämlich mittels QMetaObject::invokeMethod. Einfach den
Funktionsnamen als String übergeben und deine Funktion noch als Slot
definieren und schon sollte das klappen. Funktioniert sogar mit
Rückgabewerten deiner Funktion