Utilisation de fonctions Callback

cs_N0euX Messages postés 12 Date d'inscription lundi 5 décembre 2005 Statut Membre Dernière intervention 2 juillet 2008 - 23 juil. 2007 à 16:08
cs_N0euX Messages postés 12 Date d'inscription lundi 5 décembre 2005 Statut Membre Dernière intervention 2 juillet 2008 - 24 juil. 2007 à 17:06
 Bonjour a tous,<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /??>




 






Je suis actuellement confronte a un probleme de fonction callback.





J utilise une librairie pour controler un peripherique. Dans celle-ci, il y a une fonction dont la declaration est la suivante :






 








typedef void (WINAPI *NOTIFICATION_CALLBACK) (HANDLE cyDevice, DWORD dwNotify, DWORD dwUser);





// cyDevice = Handle to device triggering callback





// dwNotify = Reason for callback





// dwUser = User-defined parameter





// Subscribe for event notifications such as ready-to-read





// Only one subscriber callback per device





// Returns OK or an error code





DWORD SubscribeNotifications





(






    HANDLE cyDevice, // Handle obtained from Open()






    NOTIFICATION_CALLBACK callback, // Pointer-to-function for callback






    DWORD dwUser // User-defined parameter to pass to callback





);








 






Je cherche a utiliser la fonction SubscribeNotifications dans mon programme c++ mais je ne connais pas grand chose aux fonctions callback.





Pour cela, je cree une fonction telle que :






 








void WINAPI OnUser(HANDLE hanReader, DWORD dwNotify, DWORD dwUser)





{






    // mon code





}








 






Et par la suite, dans mon main, je fais appel a ma fonction Subscribe_notifications :






 








RFID_NOTIFICATION_CALLBACK callback;





callback = (RFID_NOTIFICATION_CALLBACK)OnUser;





DWORD dwUser;





cout << "Error Code sub notif " << RFID_SubscribeNotifications(hanReader,callback,dwUser) << endl;








 






Logiquement, a chaque evenement sur mon peripherique, la fonction OnUser devrait s executer (en tout cas c est mon but) mais ce n est pas le cas.. Je ne sais pas si c est moi qui ne comprends pas grand chose aux callback (c est bien possible) mais j aimerais bien savoir que faire pour corriger mon erreur svp.






 






Merci d avance.

14 réponses

acx01b Messages postés 280 Date d'inscription dimanche 7 septembre 2003 Statut Membre Dernière intervention 8 juillet 2014 6
23 juil. 2007 à 17:44
salut
pourquoi mets tu sans RFID_ puis avec RFID_ ensuite ?

ils disent HANDLE cyDevice, // Handle obtained from Open()
dans ta lib, tu as passé le bon ?
0
ctx_man Messages postés 285 Date d'inscription mardi 28 décembre 2004 Statut Membre Dernière intervention 20 janvier 2013 3
23 juil. 2007 à 18:05
Salut !
Déjà petite simplification :
RFID_SubscribeNotifications(hanReader, (NOTIFICATION_CALLBACK)OnUser, 0);
Redéfinir un pointeur local pour ton callback sert strictement à rien.
Le DWORD dwUser c'est fait pour passer un paramètre à ta fonction callback, tu t'en sert pas alors ne définit pas une varible locale pour la passer à ton callback, surtout que tu ne l'initialise pas, tu ne sais pas ce qu'il y a dedans.

Ensuite, meme remarque que acx01b, c'est marquer "NOTIFICATION_CALLBACK callback, // Pointer-to-function for callback" donc d'où vien le "(RFID_NOTIFICATION_CALLBACK)".

Et comment as-tu obtenu ton hanReader ?
0
cs_N0euX Messages postés 12 Date d'inscription lundi 5 décembre 2005 Statut Membre Dernière intervention 2 juillet 2008
23 juil. 2007 à 19:08
desole, autant pour moi je n etais trompe en recopiant mon code donc le RFID est une erreur qui n y est normalement pas (jai modifie le post en consequence)

161232 acx01b, comment sa passer le bon handler? je pensais que comme la fonction allait s executer au declenchement d un evenement, les parametres etaient transmis automatiquement.. (un peu comme en vb .net ou on peut recuperer des informations sur levenement qui se declenche, ici je pensais que les infos etaient le handler declencheur, levenement dwNotify et le dwUser d ou est issu l evenement ) sinon je ne vois pas comment gerer cela.

=411837 ctx_man, oui j ai enleve la redefinition du pointeur local, juste comme cela ne marchait pas j ai un peu tout teste (enfin, tout ce que je sais faire). Pour le parametre a passer a la fonction callback, je sais que jen ai pas besoin mais je ne sais pas quoi passer a ma fonction SubscribeNotification si je ne definis pas un DWORD quelconque..
Le hanReader est obtenu auparavant dans le main tel que "hanreader = open(1)" (1 etant le numero du periph, la fonction open marche correctement jai pu tester dautres fonctions par le suite utilisant le handreader)
0
racpp Messages postés 1909 Date d'inscription vendredi 18 juin 2004 Statut Modérateur Dernière intervention 14 novembre 2014 17
23 juil. 2007 à 19:41
Salut,
Je ne connais pas SubscribeNotification(). Elle appartient à quelle librairie?
Pour
que ta fonction CallBack soit appelée, il faut qu'elle soit
correctement enregistrée par le service de notification concerné. 
C'est sûrement le role de SubscribeNotification(). Es-tu sûr que ce service est actif?
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
ctx_man Messages postés 285 Date d'inscription mardi 28 décembre 2004 Statut Membre Dernière intervention 20 janvier 2013 3
24 juil. 2007 à 08:28
Salut, je passe en couranr juste pour te dire que j'avais répondu à "je sais que jen ai pas besoin mais je ne sais pas quoi passer a ma fonction SubscribeNotification si je ne definis pas un DWORD quelconque".

DWORD Double Mot 4 octets = 32 bits = unsigned int
petit rappel, un nombre sortit direct dans le code est un int par défaut.
RFID_SubscribeNotifications(hanReader, (NOTIFICATION_CALLBACK)OnUser, 0);
Voila le petit 0 à la place de la variable. Plus l'allocation et un paramètre que tu connais. De mannière générale, la majoritée des fonctions sont faite de telle sorte que quand tu sais pas quoi mettre comme paramettre, tu met 0 ou NULL (sachant que NULL n'est qu'un define de 0)
0
cs_N0euX Messages postés 12 Date d'inscription lundi 5 décembre 2005 Statut Membre Dernière intervention 2 juillet 2008
24 juil. 2007 à 09:51
racpp, SubscribeNotification est fournie dans la librairie de mon periph, et permet, moyennant le passage d une fonction de callback d effectuer des operations que lon veut lors de l occurence d un evenement. le service est cense s activer par cette fonction elle meme..  d apres la doc, donc si cela ne marche pas, c est que je dois mal appeler ma fonction d apres moi.. (meme si elle ne me renvoit pas une erreur) 

ctx_man, merci pr les infos, jai hesite a mettre null mais je savais pas si cela correspondait a un dword. Avec ta syntaxe, l execution est correcte mais il n execute pas de callback comme je le voudrais..
0
ctx_man Messages postés 285 Date d'inscription mardi 28 décembre 2004 Statut Membre Dernière intervention 20 janvier 2013 3
24 juil. 2007 à 10:07
En fait mettre 0 ce n'est pas tou a fait un DWORD. Le DWORD c'est un define (ou un typedef je sais plus) de unsigned int. Si tu ne met pas de préfixe/suffixe pour indiquer la nature de ta constante, alors le compilateur décide que c'est un int tout court (donc un signed int). Cependant, tant que les valeurs que tu met restent dans la fourchette positive d'un signed int, le compilo dira rien car aucun risque de perte de donnée.

Pour en revenir à ton problème : tu es absolument certain qu'il n'execute pas ton callback ?
Je veux dire par la que si ta facon de tester si ta fonction callback est appellée c'est de mettre un printf ou un messagebox a l'intérieur de cette fonction, alors tu ne peux être certain qu'elle n'est pas appellée. Met un point d'arret dans ta fonction callback, par exemple sur le return en écrivant ton callback comme suit :

void WINAPI OnUser(HANDLE hanReader, DWORD dwNotify, DWORD dwUser)
{
return; //<---point d'arret à poser ici.
}

C'est une bonne mannière d'etre sur de savoir si tu passe par ton callback ou non.

Sinon, es-tu sur que c'est tou ce qu'il faut faire ? La doc ne fait pas état d'une fonction d'initialisation du système de notification ou quelque chose à faire avant/apres ton RFID_SubscribeNotifications ?
0
cs_N0euX Messages postés 12 Date d'inscription lundi 5 décembre 2005 Statut Membre Dernière intervention 2 juillet 2008
24 juil. 2007 à 12:38
en fait je vais revenir sur mon programme.
c est une application c++ console que jappelle avec un parametre apres compil tel que "monprog param". jusque la mormal. suivant le parametre dans le main de mon programme, on discute avec le periph en lui envoyant des commandes, puis le programme termine. dans le cas present, jappelle avec /subnotif comme parametre et apres dans le main je fais donc appel a SubscribeNotifications qui est cense (d apres la doc) initialiser le systeme de notification, en lui precisant la fonction de callback (celle ci etant dans mon programme, en dehors du main). mais apres, lors de l evenement, le programme n etant pas lance, je ne vois pas comment cela peut fonctionner et comment le periph peut executer ma fonction..

ainsi, je ne sais pas comment mettre de point d arret n etant pas en debug.. pour le moment je verifie si lecriture dans un fichier est effectuee ou pas, et ce n est pas le cas.

la seule chose precisee par la doc a faire en dehors dappeler cette fonction est d autoriser l occurence des evenements qui m interessent sur le periph, et cela marche car jai pu le verifier autrement. c est juste que je narrive pas a le recuperer loccurence de cet evenement (et ainsi pouvoir le traiter).
0
ctx_man Messages postés 285 Date d'inscription mardi 28 décembre 2004 Statut Membre Dernière intervention 20 janvier 2013 3
24 juil. 2007 à 13:06
Re !
En fait, avec VS (et certainement la majoritée des IDE) tu peux passer des paramètres a ton programme en mode debug. La configuration de la ligne de commande lançant ton programme en mode debug est souvent placée dans les propriétées du projet. Tu peux donc quand même lancer ton programme en mode debug avec le point d'arret. Sinon tu peux te servir du paramètre de ta fonction calback pour passer un pointer qui te permettra de retourner une valeur ou je ne sais quoi d'autre.

Petit question : Si ton programme se termine juste apres avoir fait ton subnotif, c'est plutot normal que la callback soit pas appelé puisque le programme référencant la fonction est terminé. Donc, tu n'es pas sensé boucler sur quelque chose ?
0
cs_N0euX Messages postés 12 Date d'inscription lundi 5 décembre 2005 Statut Membre Dernière intervention 2 juillet 2008
24 juil. 2007 à 13:59
"Petit question : Si ton programme se termine juste apres avoir fait ton subnotif, c'est plutot normal que la callback soit pas appelé puisque le programme référencant la fonction est terminé. Donc, tu n'es pas sensé boucler sur quelque chose ? "

C est justement ce que je me demande, parce qu ils ne mentionnent nulle part cela.. ou alors il faut que je mette ma fonction a executer dans une librairie et le periph connait l adresse de cette fonction et lors de l occurence d un evenement va la chercher a l adresse indiquee et l execute? le periph est vraiment mal documente donc je ne sais pas trop .. mais normalement je ne pense pas devoir boucler sur quelque chose, cela serait un peu lourd de mettre une boucle qui attend la notification d un evenement.. (et quite a faire une boucle qui attend la notification, autant faire une boucle qui va voir si levenement a eu lieu directement..)
0
ctx_man Messages postés 285 Date d'inscription mardi 28 décembre 2004 Statut Membre Dernière intervention 20 janvier 2013 3
24 juil. 2007 à 14:16
Re !
Et bien oui et non, si tu fais un logiciel en mode graphique avec une belle fenêtre et tout, tu va pas bloquer la fenetre graphique en attendant d'avoir un event. Donc tu demande au périf de te prévenir plutot. Comme en appli graphique tu as forcément une boucle de message, ton appli se ferme que quand le user la quitte.

Essaye de faire une boucle "infifie" qui fait que attendre, tu verra bien si il se passe quelque chose. Dans ce cas, ca risque d'etre du pour toi car il faut garder en mémoire l'adresse de la fonction. Et cette adresse ne sera valide que pendant le temps d'execution de ton programme. A ma connaissance tu ne peux pas mettre ta fonction dans une DLL et passer l'adresse à ton subnotif. Dans la mesure où tu lui passe seulement l'adresse et pas l'url de la librairie à charger, il ne pourra pas appeller ta fonction car elle ne sera pas valide dans le contexte de subnotif.
0
cs_N0euX Messages postés 12 Date d'inscription lundi 5 décembre 2005 Statut Membre Dernière intervention 2 juillet 2008
24 juil. 2007 à 15:11
ouais c est bien ce que je me disais, cela me paraissait etrange! il faut donc que je garde le prog lance.. merci
0
acx01b Messages postés 280 Date d'inscription dimanche 7 septembre 2003 Statut Membre Dernière intervention 8 juillet 2014 6
24 juil. 2007 à 16:13
salut

la prochaine fois donne le code avec
0
cs_N0euX Messages postés 12 Date d'inscription lundi 5 décembre 2005 Statut Membre Dernière intervention 2 juillet 2008
24 juil. 2007 à 17:06
desole, jai donne le code qui me semblait important, l ensemble faisant plus de 500 lignes je n allais pas tout mettre...
0
Rejoignez-nous