 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
Michael Guest
|
Posted: Sat Mar 04, 2006 9:06 am Post subject: callback de pointeur de fonction membre |
|
|
Bonjour à tous,
j'ai Windows qui me cause quelques soucis, liés à des callbacks de
fonction.
J'ai par exemple le pointeur de fonction suivant:
typedef void (*LPDXUTCALLBACKFRAMEMOVE)( int i );
J'ai la fonction suivante qui permet d'attribuer un callback:
void WINAPI DXUTSetCallbackFrameMove(LPDXUTCALLBACKFRAMEMOVE pCallback )
{
GetDXUTState().SetFrameMoveFunc(pCallback );
}
Et qui est utilisée
DXUTSetCallbackFrameMove( NewOnFrameMove );
avec
void NewOnFrameMove(int i)
{
//Traitement
}
Seulement j'aimerai incorporer ces fonctions de callback au sein d'une
classe. Seulement bien sûr je ne peux pas attribuer un pointeur de
fonction membre.
J'ai contourné le problème en définissant une fonction membre statique,
qui redirige vers une fonction membre non statique, via un pointeur de la
classe statique.
Je ne pense pas que ce que je viens de dire soit d'une clarté absolue,
donc un petit exemple...
class foo
{
private:
static foo * f;
static void StaticOnFrameMove( int i);
void OnFrameMove(int i);
public:
foo();
}
foo::foo()
{
f = this;
}
void foo::StaticOnFrameMove(int i)
{
f->OnFrameMove(i);
}
void foo::OnFrameMove(int i);
{
//Traitement
}
Est-ce une manière courante de fonctionner? Sinon quelles autres
alternatives s'offrent à moi?
Merci d'avance
Mike |
|
| Back to top |
|
 |
James Kanze Guest
|
Posted: Sat Mar 04, 2006 4:55 pm Post subject: Re: callback de pointeur de fonction membre |
|
|
Michael wrote:
| Quote: | j'ai Windows qui me cause quelques soucis, liés à des
callbacks de fonction.
J'ai par exemple le pointeur de fonction suivant:
typedef void (*LPDXUTCALLBACKFRAMEMOVE)( int i );
J'ai la fonction suivante qui permet d'attribuer un callback:
void WINAPI DXUTSetCallbackFrameMove(LPDXUTCALLBACKFRAMEMOVE pCallback )
{
GetDXUTState().SetFrameMoveFunc(pCallback );
}
Et qui est utilisée
DXUTSetCallbackFrameMove( NewOnFrameMove );
avec
void NewOnFrameMove(int i)
{
//Traitement
}
Seulement j'aimerai incorporer ces fonctions de callback au
sein d'une classe. Seulement bien sûr je ne peux pas attribuer
un pointeur de fonction membre.
|
Ni même, si l'API est définie en C, une fonction qui n'est pas
« extern "C" ».
| Quote: | J'ai contourné le problème en définissant une fonction membre
statique, qui redirige vers une fonction membre non statique,
via un pointeur de la classe statique.
|
Je ne connais pas l'API que tu utilises, mais la plupart de
temps, en plus de l'adresse de la fonction, tu passes un
pointeur à des données (un void*) -- c'est le cas de tous les
interfaces bien conçues, et c'est le cas, d'après ce que j'ai
entendu dire, de la plupart des call-backs dans l'API de
Windows. La solution classique est alors quelque chose du
genre :
extern "C" void /* ou ce qu'il faut, évidemment */
callback( void* p )
{
static_cast< MaClasse* >( p )->laFonctionQuIlFaut() ;
}
On passe alors l'adresse de callback, et l'adresse de l'objet.
(Ce qu'on aimerait, ici, c'est un espèce de template pour
callback. Ce que le « extern "C" » rend impossible. Reste les
macros, si le cas se présente souvent.)
| Quote: | Je ne pense pas que ce que je viens de dire soit d'une clarté
absolue,
|
Mais si... C'est un problème on ne peut plus connu, du fait
qu'il y a tellement d'API définies en C.
[...]
| Quote: | Est-ce une manière courante de fonctionner? Sinon quelles
autres alternatives s'offrent à moi?
|
S'il n'y a pas de paramètre void*, il n'y a pas beaucoup
d'autres solutions. Mais il pose un problème dès qu'on veut
inscrire la même fonction plusieurs fois, mais sur des données
différentes.
Parfois, tu peux le contourner aussi avec un std::map et
d'autres informations. Si, par exemple, tu as un callback par
élément graphique, et que l'API te donne une indentificateur de
l'élément graphique, tu peux faire quelque chose du genre :
static std::map< GUIId, MaClasse* > objectMap ;
extern "C" void
callback( CUIId id )
{
objectMap[ id ]->f() ;
}
--
James Kanze kanze.james (AT) neuf (DOT) fr
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France +33 (0)1 30 23 00 34 |
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|