Die übergabe von Parametern dynamisch zu variadischen Funktionen
Ich Frage mich, ob es irgendeinen Weg, um Parameter dynamisch zu variadischen Funktionen. d.h. Wenn ich eine Funktion
int some_function (int a, int b, ...){/*blah*/}
und ich bin der Annahme einer Reihe von Werten vom Benutzer, ich will Weg dar, diese Werte in der Funktion:
some_function (a,b, val1,val2,...,valn)
Möchte ich nicht schreiben, verschiedene Versionen von all diese Funktionen, aber ich vermute, es gibt keine andere option?
- wenn alle Werte vom selben Typ (wie deine Frage scheint zu implizieren - korrigieren Sie mich, wenn ich falsch Liege), würde ich vorschlagen, nicht zu verwenden, eine Variable Funktion, und übergeben Sie ein array statt; siehe hier für einige makro-Magie pretty it up, wenn Sie wollen, zu passieren, in eine Feste Anzahl von Argumenten: stackoverflow.com/questions/1375474/variable-arity-in-c/...
- Nein, Sie sind von verschiedenen Arten.
- der array-Ansatz kann weiterhin funktionieren, wenn Sie wickeln Sie Ihre Werte in einer Gewerkschaft oder übergeben in einem array von
void *
um die Werte statt der Werte selbst, aber es werden weniger elegant - Übergeben Sie ein array von void* klingt wie die ideale Lösung eigentlich, ich glaube nicht, dass das funktionieren würde.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Variadic-Funktionen verwendet eine Aufrufkonvention, wo der Aufrufer ist dafür verantwortlich knallen der Funktion Parameter aus dem stack, also ja, es ist möglich dies dynamisch. Es ist nicht standardisiert in C, und normalerweise würde erfordern einige Montage manuell drücken Sie den gewünschten Parameter, und rufen Sie die Variable Funktion korrekt.
Den
cdecl
Aufruf-Konvention verlangt, dass die Argumente, die geschoben werden, in der richtigen Reihenfolge, und nach dem Aufruf werden die bytes geschoben als Argumente vor dem Aufruf geholt werden. Auf diese Weise wird die aufgerufene Funktion empfangen kann eine beliebige Anzahl von Parametern, wie der Aufrufer behandelt zurücksetzen der stack-pointer um es in den pre-call-state. Der belegte Speicherplatz durch die Argumente vor der...
ist die sichere untere Schranke für die Anzahl der bytes geschoben. Zusätzliche Variable Argumente interpretiert zur Laufzeit.FFCALL ist eine Bibliothek, die mit wrappers zur übergabe von Parametern dynamisch zu variadischen Funktionen. Die Gruppe der Funktionen, die Sie interessiert, ist,avcall. Hier ist ein Beispiel für den Aufruf der Funktionen, die Sie gab oben:
Vielleicht finden Sie auch dieser link diskutieren Generierung von Wrapper variadischen Funktionen in C, zum des Interesses zu rechtfertigen, warum dies ist nicht Teil von standard-C.
Standard-Ansatz wird jede Variable Funktion begleitet von einem
va_list
-Einnahme Gegenstück (wie bei printf und Funktionen vprintf). Die variadic version nur konvertiert...
zu einemva_list
(mit Makros ausstdarg.h
) und nennt seine va_list-Einnahme Schwester, die nicht die eigentliche Arbeit.Könnte es interessant sein, zu versuchen, einfach ein array übergeben, und verwenden Sie dann die vararg-Makros sowieso. Je nach stack-Ausrichtung, könnte es Nur die Arbeit (tm).
Dies ist wahrscheinlich nicht die optimale Lösung, habe ich hauptsächlich gepostet, weil ich fand die Idee interessant.
Nach dem Versuch es heraus, dieser Ansatz funktioniert auf meinem linux-x86, aber nicht auf x86-64 - es kann wahrscheinlich verbessert werden. Diese Methode hängt vom Stapel Ausrichtung, Struktur, Ausrichtung und wahrscheinlich noch mehr.
Je nachdem, was es ist, du bist vorbei, es könnte sein, diskriminiert union sind Sie nach hier (wie schon angedeutet, in den Kommentaren). Das wäre zu vermeiden die Notwendigkeit für variadic functions oder arrays von
void*
und beantwortet die Frage "wie funktioniert some_function wissen, was Sie eigentlich ging es". Haben Sie vielleicht etwas code wie dieser:Können Sie noch einen Schritt weiter und vermeiden Sie die Schalter durch den Austausch der
code
mit einem oder mehreren Zeigern auf Funktionen, die etwas nützliches tun mit jedemthing
. Zum Beispiel, wenn das, was Sie tun wollte, war zu einfach drucken Sie jede Sache, die Sie haben könnten dieser: