
Wer bin ich
In bestimmten Situationen in meinem Code rufe ich die Funktion nur auf, wenn diese Funktion definiert ist, oder ich sollte es nicht tun. Wie kann ich das erreichen?
like:
if (function 'sum' exists ) then invoke sum ()
Vielleicht anders herum, um diese Frage zu stellen, wie kann man feststellen, ob die Funktion zur Laufzeit definiert ist, und wenn ja, dann aufrufen?

matu
Wenn Sie “Summe” deklarieren, können Sie es wie folgt deklarieren:
#define SUM_EXISTS
int sum(std::vector<int>& addMeUp) {
...
}
Wenn Sie es dann verwenden, können Sie Folgendes tun:
#ifdef SUM_EXISTS
int result = sum(x);
...
#endif
Ich vermute, Sie kommen aus einer Skriptsprache, in der alles zur Laufzeit erledigt wird. Das Wichtigste, woran man sich bei C++ erinnern sollte, sind die zwei Phasen:
- Kompilierzeit
- Präprozessor läuft
- Vorlagencode wird in echten Quellcode umgewandelt
- Quellcode wird in Maschinencode umgewandelt
- Laufzeit
- Der Maschinencode wird ausgeführt
Also alle #define
und solche Dinge passieren zur Kompilierzeit.
….
Wenn Sie wirklich alles zur Laufzeit erledigen wollten, könnten Sie daran interessiert sein, einige der zu verwenden Komponentenarchitekturprodukte dort draußen.
Oder vielleicht ein Plugin-Art von Architektur ist, was Sie suchen.

Basile Starynkevitch
Während andere Antworten hilfreiche Ratschläge sind (dlsym
Funktionszeiger, …), Sie kann nicht kompilieren C++-Code, der auf eine Funktion verweist, die nicht existiert. Die Funktion muss mindestens sein erklärt; Wenn dies nicht der Fall ist, wird Ihr Code nicht kompiliert. Wenn nichts (eine Kompilierungseinheit, eine Objektdatei, eine Bibliothek) definiert die Funktion würde der Linker bemängeln (es sei denn, er ist schwach, siehe unten).
Aber du solltest wirklich erklären, warum du das fragst. Ich kann es nicht erraten, und es gibt einen Weg, Ihr unausgesprochenes Ziel zu erreichen.
Beachte das dlsym
erfordert oft Funktionen ohne Namensverstümmelungdh deklariert als extern "C"
.
Wenn Sie unter Linux mit GCC programmieren, können Sie auch die weak
Funktionsattribut bei Deklarationen. Der Linker würde dann undefinierte schwache Symbole auf null setzen.
Nachträge
Wenn Sie den Funktionsnamen aus einer Eingabe erhalten, sollten Sie sich darüber im Klaren sein, dass nur eine Teilmenge von Funktionen auf diese Weise aufrufbar sein sollte (wenn Sie eine beliebige Funktion ohne Sorgfalt aufrufen, stürzt sie ab!) und Sie sollten diese Teilmenge besser explizit konstruieren . Dann könntest du a verwenden std::map
oder dlsym
(wobei jede Funktion in der Teilmenge deklariert ist extern "C"
). Beachte das dlopen
mit einer NULL
Pfad gibt dem Hauptprogramm ein Handle, mit dem Sie verknüpfen sollten -rdynamic
damit es richtig funktioniert.
Sie möchten wirklich nur eine geeignet definierte Teilmenge von Funktionen mit ihrem Namen nennen. Zum Beispiel möchten Sie wahrscheinlich nicht auf diese Weise anrufen abort
, exit
oder fork
.
NB. Wenn Sie wissen dynamisch die Signatur der aufgerufenen Funktion, die Sie vielleicht verwenden möchten libffi um es zu nennen.
Mit GCC können Sie:
void func(int argc, char *argv[]) __attribute__((weak)); // weak declaration must always be present
// optional definition:
/*void func(int argc, char *argv[]) {
printf("ENCONTRE LA FUNC\n");
for(int aa = 0; aa < argc; aa++){
printf("arg %d = %s \n", aa, argv[aa]);
}
}*/
int main(int argc, char *argv[]) {
if (func){
func(argc, argv);
} else {
printf("no encontre la func\n");
}
}
Wenn Sie func auskommentieren, wird es ausgeführt, andernfalls wird “no encontre la func\n” ausgegeben.

fredbaba
Ich vermute, dass das Poster tatsächlich nach etwas mehr in der Art von SFINAE-Prüfung / -Versand gesucht hat. Mit C++-Vorlagen können Vorlagenfunktionen definiert werden, eine, die die gewünschte Funktion aufruft (falls vorhanden) und eine, die nichts tut (falls die Funktion nicht vorhanden ist). Sie können dann die erste Vorlage von der gewünschten Funktion abhängig machen, sodass die Vorlage schlecht geformt ist, wenn die Funktion nicht vorhanden ist. Dies ist gültig, da in C++ ein Fehler bei der Vorlagenersetzung kein Fehler ist (SFINAE), sodass der Compiler einfach auf den zweiten Fall zurückgreift (der beispielsweise nichts tun könnte).
Ein hervorragendes Beispiel finden Sie hier: Ist es möglich, eine Vorlage zu schreiben, um die Existenz einer Funktion zu überprüfen?
Verwenden Sie Zeiger auf Funktionen.
//initialize
typedef void (*PF)();
std::map<std::string, PF> defined_functions;
defined_functions["foo"]=&foo;
defined_functions["bar"]=&bar;
//if defined, invoke it
if(defined_functions.find("foo") != defined_functions.end())
{
defined_functions["foo"]();
}
Wenn Sie wissen, in welcher Bibliothek sich die Funktion befindet, die Sie aufrufen möchten, können Sie sie verwenden dlsym()
und dlerror()
um herauszufinden, ob es da ist oder nicht, und was der Zeiger auf die Funktion ist.
Bearbeiten: Ich würde diesen Ansatz wahrscheinlich nicht wirklich verwenden – stattdessen würde ich Matius Lösung empfehlen, da ich denke, dass dies eine viel bessere Übung ist. Jedoch, dlsym()
ist nicht sehr bekannt, also dachte ich, ich würde darauf hinweisen.

matu
Sie können verwenden #pragma weak
für die Compiler, die es unterstützen (siehe die schwaches Zeichen Wikipedia-Eintrag).
Dieses Beispiel und dieser Kommentar stammen von Die Insider-Geschichte zu gemeinsam genutzten Bibliotheken und dynamischem Laden:
#pragma weak debug
extern void debug(void);
void (*debugfunc)(void) = debug;
int main() {
printf(“Hello World\n”);
if (debugfunc) (*debugfunc)();
}
Sie können das schwache Pragma verwenden, um den Linker zu zwingen, nicht aufgelöste Symbole zu ignorieren [..] das Programm kompiliert und verlinkt, ob debug() tatsächlich in einer Objektdatei definiert ist oder nicht. Wenn das Symbol undefiniert bleibt, ersetzt der Linker normalerweise seinen Wert durch 0. Daher kann diese Technik eine nützliche Möglichkeit für ein Programm sein, optionalen Code aufzurufen, der nicht die Neukompilierung der gesamten Anwendung erfordert.
10191100cookie-checkWie überprüfe ich, ob eine Funktion in C/C++ existiert?yes
Sie müssten irgendeine Art von ladbarer Bibliotheksunterstützung verwenden, zB dlopen
– Irgendein Korn
11. Januar 2012 um 5:47 Uhr
Wie genau schlagen Sie vor, in eine Situation zu kommen, in der Sie anrufen möchten?
sum
aber sind nicht sicher, ob es existiert? Sie sollten wissen, ob es existiert; Du bist derjenige, der den Code schreibt!– Karl Knechtel
11. Januar 2012 um 6:14 Uhr
Du solltest wirklich erklären, warum du fragst. In welchem Zusammenhang braucht man das? Das habe ich in 35 Jahren Programmieren in keiner kompilierten Sprache gebraucht …
– Basile Starynkevitch
11. Januar 2012 um 6:21 Uhr
Ich erhalte den Funktionsnamen als Parameter von der Befehlszeile und muss ihn ausführen, falls vorhanden.
– Wer bin ich
11. Januar 2012 um 6:21 Uhr
@whoami: In diesem Fall musst du so etwas tun
if(string(argv[1]) == "sum") { sum(); }
.– Naveen
11. Januar 2012 um 6:24 Uhr