Funktionen zur Laufzeit erstellen // Funktionszeiger-Liste
-
Schon mal mit Klassen und Objekten gearbeitet?
-
ist mir schon klar, dass das eine sehr stumpfsinnige Frage ist, die ich anbiete.
Der Grund dafür liegt dartin, dass ich auf eine Event-Funktion aus einer Library zugreife,die mir nur diesen Typ erlaubt:
void Func(long lInput) // wobei der long Wert die Adresse der Funktion übernimt
Ich verstecke also den Index im Funktionsnamen - und um das halbwegs erträglich zu machen, schreibe ich dann den Array.
Der Hintergrund ist natürlich: Übergabe eines Methodenzeigers - aber wie man sieht, gerät mir der Mangel an Argmumenten einfach zum Problem.
Danke schön für die Anteilnahme, vieleicht doch jemand da, der meine Begriffsblockade auflöst.
Das habe ich leider gar nicht verstanden:
std::tr1::bindWie müsste ich das machen?
-
Wieso übergibst du nicht einen Pointer auf ein Objekt als Parameter, statt nen Funktionspointer. Ist das wirklich long als Parameter? Klingt für mich etwas gefährlich davon auszugehen, dass ein Pointer immer in long passt
-
Naja, auch wenn ich nicht ganz verstehe, wieso du nur so eine Funktion mit dieser Signatur verwenden kannst, so gäbe es vielleicht eine Möglichkeit:
template<int iIndex> void Func(long lInput) { vMETAPANEL[iIndex].TriggerToolbar0(lInput); }; // Verwendung: funktion_zur_api_oder_was_auch_immer(&Func<0>); funktion_zur_api_oder_was_auch_immer(&Func<3>);Es müsste aber zur Compilezeit bekannt sein, was für eine Nummer, wann aufgerufen wird.
Ansonsten kannst du vielleicht so die Sache ein wenig schneller erstellen lassen:
void InitFunctions() { Function[0] = &Func<0>; Function[1] = &Func<1>; // usw. }Aber wie gesagt, verstanden habe ich deine Problemstellung nicht und von mir aus gesehen ist hier irgendwo ein Designfehler.
Grüssli
-
Dravere schrieb:
Aber wie gesagt, verstanden habe ich deine Problemstellung nicht und von mir aus gesehen ist hier irgendwo ein Designfehler.
Ist es, aber in der Bibliothek

@Standardkundige, ist sowas konform?
void tolle_funktion_die_aufruft (int Index) { struct Bla { static void func (long Input) { vMETAPANEL[Index].TriggerToolbar0(Input); } } gangsta_bibliotheks_funktion (&Bla::func); }Wobei das wohl spätestens dann ziemlich in die Hose geht, wenn gangsta_bibliotheks_funktion den Zeiger speichert ...
Hmm, Percy, ich glaub' dir bleibt tatsächlich kaum was anderes übrig (bind würde nur helfen, wenn beliebige Funktionsobjekte erlaubt wären). Um dir die Arbeit etwas zu vereinfachen und den Code zu verkürzen, könntest du ihn mit Boost.Preprocessor oder mit tollen Metaprogrammen erzeugen lassen.
template <unsigned I> struct meta_function_init { static void func (long Input) { vMETAPANEL[I].TriggerToolbar0(Input); } meta_function_init (std::vector<function>& array) { meta_function_init<I - 1> blubb (array); array.push_back (&meta_function_init::func); } } template <> struct meta_function_init<0> { static void func (long Input) { vMETAPANEL[0].TriggerToolbar0(Input); } meta_function_init (std::vector<function>& array) { array.push_back (&meta_function_init::func); } };Und dann
void InitFunctions () { meta_function_init<TOLLE_GROßE_KONSTANTE> initer (array); }/edit: Danke Dravere

-
*hüstel*
.filmor? Hast du da nicht irgendwas vergessen? Deine Methoden sind nicht static und somit Member-Funktionen und können daher nicht ohne Objekt aufgerufen werden
Wenn man allerdings vor dasvoid func(long lInput)einstaticeinbauen würde, dann denke ich, sollte sowas funktionieren.Grüssli
-
Percy2000 schrieb:
Der Grund dafür liegt dartin, dass ich auf eine Event-Funktion aus einer Library zugreife,die mir nur diesen Typ erlaubt:
void Func(long lInput) // wobei der long Wert die Adresse der Funktion übernimt
Bedank dich bei den Idioten, die diese API entworfen haben. Da man keine zusätzlichen Daten übergeben kann hast du ganz einfach verloren.
-
@Percy2000
Ich kenne das Problem, und ich kenne eigentlich nur eine komplett generische Lösung: Thunks zu erzeugen, indem man Speicher alloziert und da Code reinschreibt, und den Zeiger dann auf einen Funktionszeiger castet. Ist natürlich komplett überhaupt nicht portierbar und ziemlich ... hässlich.Wenn du wissen willst wie sowas aussieht guck dir die Implementierung der Window-Klassen in der ATL an, da werden solche dynamisch erzeugten Thunks verwendet.
-
@hustbear:
die idee ist gut. Wenn man aber codesnippets prozessorspezifisch compiled, die dann, je nach art kombiniert, in den speicher gelegt werden, dürfte das auch portierbar sein. Man müsste sich dann bloß noch n kleenes köpfchen für den datenaustausch zwischen den snippets machen. (Gibts da keine lib für??)
Gibt es aber i.A. keine javascript ähnliche func. eval() für c/c++ ??grüüüße
-
Ich glaub nicht, dass es darum geht Code zur Laufzeit zu erzeugen.
-
@zeusosc: Es geht hier eigentlich nur darum Thunks zu erzeugen (wenn überhaupt), und dafür reicht ein "snippet" pro Prozessor und Funktionstyp (Anzahl & Typ der Parameter + Returntyp).