dynamik bei funktionsaufrufen
-
nehmen wir an wir haben 500 funktionen
ob funktionspointer oder nicht sei dahingestelltnun haben wir noch einen array variabler grösse, der unterschiedliche datentypen enthält
array[DataObj*];
mit
array[0]->GetDataType();
könnten wir z.b. prüfen obs n long/double/string/memblock etc. isdie frage is nun... kann ich folgenden code irgendwie abkürzen
switch ( functionid ) { case 0: func0( array[0], array[1], array[2] ); case 1: func1( array[0] ); ... ... case 498: func498( array[0], array[1] ); case 499: func499( array[0], array[1], array[2], array[3] ); }
quasi irgendwie die funktionen dynamisch aufrufen
das ganze is teil von ner art remoteinterface in dem ein lokaler rechner aufgerufene funktionen eines standardinterfaces der software zu einem remoterechner zur bearbeitung schickt und das ergebnis zurückliefert als hätte ers lokal berechnet
-
*schieb*
-
in eine std::map<id, funktion> packen.
dann machst du nur noch
map[id](juhu);
zum aufrufen der passenden funktiondazu muesstest du aber die funktionen angleichen. dazu zB eine struktur als parameter uebergeben wo die passenden werte drinnen stehen.
-
ne die funktionen müssten gleich bleiben
ansonsten wär der arbeitsaufwand der selbe weil ich jede funktion einzeln anpassen muss
-
Sovok schrieb:
ne die funktionen müssten gleich bleiben
ansonsten wär der arbeitsaufwand der selbe weil ich jede funktion einzeln anpassen mussvielleicht kannste variable parameterlisten einsetzen und dann die function-id mitgeben. guckst du: http://www.fh-fulda.de/~klingebiel/c-stdlib/stdarg.htm
...aber wenn sich für jede function-id die bearbeiteung komplett unterscheidet, dann musste wohl oder übel für jede einen eigenen code-abschnitt haben (kommt also auf das gleiche raus). musst halt sehen dass du so viele gemeinsamkeiten wie möglich findest und die dann in funktionen auslagerst
-
gibts bei der variante ne möglichkeit rauszufinden, wieviele argumente die funktion hat und ob der aufruf von va_arg erfolgreich war?
int val = va_arg( list, int); //val is nu == 0 //heisst das 0 wurde übergeben oder der aufruf war ned erfolgreich? :-/
habs mir mal genauer angeschaut
list is ja einfach n array mit pointern auf die übergebenen argumente
so wies ausschaut is da kein hauch von typensicherheit vorhanden
wenn ich nen char* übergebe und mit int val = va_arg( list, int); abfrage,
steht in val die adresse des char pointers
-
Sovok schrieb:
gibts bei der variante ne möglichkeit rauszufinden, wieviele argumente die funktion hat und ob der aufruf von va_arg erfolgreich war?
ich glaub nicht, aber man kann ja z.b. die anzahl der argumente als erstes argument angeben
-
Man sollte aber Bedenken, dass das Verhalten der Ellipse mit Objekten nicht definiert ist.
-
Wie wär's denn hiermit:
// Ueberladungen fuer vlt. 0-10 Argumente... template <typename ReturnT, typename Par1T, typename Par2T> size_t numArgs( ReturnT (*)(Par1T, Par2T) ) { return 2; } template <typename ReturnT, typename Par1T, typename Par2T, typename Par3T> size_t numArgs( ReturnT (*)(Par1T, Par2T, Par3T) ) { return 3; } // dto, 0-10 oder so template <typename FunctionPtrT, typename Par1T, typename Par2T> void callhelper2( FunctionPtrT f, Par1T p1, Par2T p2 ) { f(p1, p2); } template <typename FunctionPtrT, typename Par1T, typename Par2T, typename Par3T> void callhelper3( FunctionPtrT f, Par1T p1, Par2T p2, Par3T p3 ) { f(p1, p2, p3); } struct FunctionWrapperBase { virtual void call( array& args ) = 0; virtual ~FunctionWrapperBase() { } }; template<typename FunctionPtrT> class FunctionWrapper : public FunctionWrapperBase { public: FunctionWrapper( FunctionPtrT funptr ) : funptr(funptr) { } void call( array& args ) { switch(numArgs(funptr)) { // dto, 0-irgendwas case 2: callhelper2(funptr, toType(args[0]), toType(args[1])); break; case 3: callhelper3(funptr, toType(args[0]), toType(args[1]), toType(args[2])); break; }; } private: FunctionPtrT funptr; }; // ... typedef std::map<id_t, FunctionWrapperBase*> FunctionMap; FunctionMap myfunctions; // ... myfunctions[id]->call(myargs);
Könntest auch verschiedene Wrapper basteln und dir von einer Factory den richtigen erzeugen lassen um das switch statement loszuwerden.