C++ callback as member function

Fórumok

Hozzászólások

Az elso namespace-gondnak tunik. Lehet hogy az megoldja a tobbit is.

Ez tipikus példa a rosszul megdesignolt API-ra. Ha már C módon gondolkodnak, akkor callbacknek kéne valami "void *userdata" jellegű paraméterének lennie, hogy át tudd adni az osztályod címét. Vagy használhatnának std::function-t a C fvptr helyett.

Szerintem ezzel sokat nem tudsz csinálni. Ha csak 1 példány van az osztályodból, akkor egy globális változón keresztül tudsz rá hivatkozni a callbackből. Ha több példány van, akkor valszeg nincs normális megoldás erre (esetleg, ha tudod, hogy melyik object callback-jét várod következőnek, akkor globális változóba be tudod tenni).

> akkor valszeg nincs normális megoldás erre

Dehogynem 1: Lérehozol egy rakás függvényt kódgenerátorral, annyit, hogy minden callbacknek másikat tudj adni. Berakod őket egy tömbbe, és onnan használod őket index szerint. Minden fv azzal kezdődik, hogy meghívja a generikus handlert egy indexszel. Az index alapján pedig egy tömbben eléred a hozzá tartozó ojjektumot.

fvpointer [1000] = {fv1, fv2, ...};
ojjekt [1000];

void fv1()
{
 callback(ojjekt[1]);
}
void fv2()
{
 callback(ojjekt[2]);
}
void fv3()
{
 callback(ojjekt[3]);
}
void fv4()
{
 callback(ojjekt[4]);
}
...
static nextIndex = 0;

registerCallback(ojekt)
{
ojjekt[nextIndex]=ojekt;
register(fvpointer[nextIndex++]);
}

Dehogynem 2: Debuggerrel megnézed, hogy mennyivel kell visszalépkedni a stacken, hogy kiolvashass valami azonosítót, hiszen a hívó program tuti, hogy tárol valahol valamit. Beteszed a mágikus konstansokat a programba, és simán kiolvasod az értéket pl így:

void callback()
{
 int dummy;
 int * ptr=dummy+mágikusszám;
 int azonosító=*ptr;
 ...
}

 

Két teljesen normális megoldás is van a problémára :-) Ha többet gondolkodnék talán jönne még hasonló...

Maradjunk annyiban, hogy ez eléggé szubjektív, hogy ezek a megoldások normálisak-e. Tutira nem csinálnám egyiket se. Akkor inkább már az eredeti libet módosítanám, ha jól nézem megvan a forráskódja, valszeg eléggé egyszerű beletenni egy "void *userdata" pointert a callbackbe.