J'aimerais utiliser une fonction membre d'une classe comme une fonction callback.
Par exemple pour utiliser une thread : pthread_create (&th, NULL, MaClasse::MaFonction, NULL);
Si MaFonction est déclarée en static, ça fonctionne.
Même ça n'est pas garanti, car à mon avis, pthread_create nécessite comme argument un pointeur sur une fonction qualifiée 'extern "C"'. Les fonctions C++ et C ne sont pas forcement interchangeables entre elles, non seulement à cause du "name mangling" (qui n'intervient pas lorsque l'appel se fait par pointeur) mais aussi parce que la "calling convention" (Passage des paramètres dans des registres ou sur la pile ? Dans quel ordre ? Qui fait le ménage sur la pile au retour - la fonction appelée ou la fonction appelante ? Comment passer la valeur de retour ?) peut différer entre les deux langages. Certains compilateurs (par exemple GCC) acceptent la conversion sans problème (soit ils utilisent la même convention d'appel, soit ils génèrent un bout de code faisant les conversions nécessaires s'il en y a besoin) mais cela reste non portable.
(À mon avis, ça serait *Bien* si une nouvelle release de la Norme C++ mandatait un comportement satisfaisant dans tous les cas...)
Mais est-ce possible avec une fonction membre non statique ?
Non.
Il faudrait pouvoir donner dynamiquement l'adresse de la fonction ... non ?
??
La technique classique la suivante (je détaille pas trop, c'est souvent posé ici, regarde google pour plus de détails).
Là, il faut faire attention à ce que la durée de vie de l'objet 'c' ne soit pas plus courte que celle du (de la ?) "thread" crée(e) ! Donc il faudrait déclarer 'c' comme 'static' ou global (attention alors à la création possible de plusieurs threads qui accèdent au même objet), ou bien créer un objet dynamique qui ne devra être détruit qu'une fois quand l[ea] thread en question est terminé(e).
Falk
Loïc Joly wrote:
Eric Bart wrote:
Bonjour,
J'aimerais utiliser une fonction membre d'une classe comme une fonction
callback.
Par exemple pour utiliser une thread :
pthread_create (&th, NULL, MaClasse::MaFonction, NULL);
Si MaFonction est déclarée en static, ça fonctionne.
Même ça n'est pas garanti, car à mon avis, pthread_create nécessite
comme argument un pointeur sur une fonction qualifiée 'extern "C"'.
Les fonctions C++ et C ne sont pas forcement interchangeables entre
elles, non seulement à cause du "name mangling" (qui n'intervient
pas lorsque l'appel se fait par pointeur) mais aussi parce que
la "calling convention" (Passage des paramètres dans des registres
ou sur la pile ? Dans quel ordre ? Qui fait le ménage sur la pile
au retour - la fonction appelée ou la fonction appelante ? Comment
passer la valeur de retour ?) peut différer entre les deux langages.
Certains compilateurs (par exemple GCC) acceptent la conversion
sans problème (soit ils utilisent la même convention d'appel, soit
ils génèrent un bout de code faisant les conversions nécessaires
s'il en y a besoin) mais cela reste non portable.
(À mon avis, ça serait *Bien* si une nouvelle release de la Norme
C++ mandatait un comportement satisfaisant dans tous les cas...)
Mais est-ce possible avec une fonction membre non statique ?
Non.
Il faudrait pouvoir donner dynamiquement l'adresse de la fonction ...
non ?
??
La technique classique la suivante (je détaille pas trop, c'est souvent
posé ici, regarde google pour plus de détails).
Là, il faut faire attention à ce que la durée de vie de l'objet 'c'
ne soit pas plus courte que celle du (de la ?) "thread" crée(e) !
Donc il faudrait déclarer 'c' comme 'static' ou global (attention
alors à la création possible de plusieurs threads qui accèdent
au même objet), ou bien créer un objet dynamique qui ne devra être
détruit qu'une fois quand l[ea] thread en question est terminé(e).
J'aimerais utiliser une fonction membre d'une classe comme une fonction callback.
Par exemple pour utiliser une thread : pthread_create (&th, NULL, MaClasse::MaFonction, NULL);
Si MaFonction est déclarée en static, ça fonctionne.
Même ça n'est pas garanti, car à mon avis, pthread_create nécessite comme argument un pointeur sur une fonction qualifiée 'extern "C"'. Les fonctions C++ et C ne sont pas forcement interchangeables entre elles, non seulement à cause du "name mangling" (qui n'intervient pas lorsque l'appel se fait par pointeur) mais aussi parce que la "calling convention" (Passage des paramètres dans des registres ou sur la pile ? Dans quel ordre ? Qui fait le ménage sur la pile au retour - la fonction appelée ou la fonction appelante ? Comment passer la valeur de retour ?) peut différer entre les deux langages. Certains compilateurs (par exemple GCC) acceptent la conversion sans problème (soit ils utilisent la même convention d'appel, soit ils génèrent un bout de code faisant les conversions nécessaires s'il en y a besoin) mais cela reste non portable.
(À mon avis, ça serait *Bien* si une nouvelle release de la Norme C++ mandatait un comportement satisfaisant dans tous les cas...)
Mais est-ce possible avec une fonction membre non statique ?
Non.
Il faudrait pouvoir donner dynamiquement l'adresse de la fonction ... non ?
??
La technique classique la suivante (je détaille pas trop, c'est souvent posé ici, regarde google pour plus de détails).
Là, il faut faire attention à ce que la durée de vie de l'objet 'c' ne soit pas plus courte que celle du (de la ?) "thread" crée(e) ! Donc il faudrait déclarer 'c' comme 'static' ou global (attention alors à la création possible de plusieurs threads qui accèdent au même objet), ou bien créer un objet dynamique qui ne devra être détruit qu'une fois quand l[ea] thread en question est terminé(e).
Falk
drkm
"Eric Bart" writes:
Il faudrait pouvoir donner dynamiquement l'adresse de la fonction
Si par « dynamiquement » tu entends « à l'exécution », c'est bien le cas.
--drkm, en recherche d'un stage : http://www.fgeorges.org/ipl/stage.html
Mais est-ce possible avec une fonction membre non statique ?
Non.
OK. Merci
Eric Bart
"drkm" wrote in message news:
"Eric Bart" writes:
Il faudrait pouvoir donner dynamiquement l'adresse de la fonction
Si par « dynamiquement » tu entends « à l'exécution », c'est bien le cas.
Oui c'est ce que je voulais dire.
Mon idée était mauvaise, je pensais pouvoir convertir l'adresse d'une fonction membre en une adresse de fonction callback. Ca ne doit pas être possible ...
"drkm" <usenet.fclcxx@fgeorges.org> wrote in message news:wk8yc2uf8z.fsf@fgeorges.org...
Il faudrait pouvoir donner dynamiquement l'adresse de la fonction
Si par « dynamiquement » tu entends « à l'exécution », c'est bien le
cas.
Oui c'est ce que je voulais dire.
Mon idée était mauvaise, je pensais pouvoir convertir l'adresse d'une fonction
membre en une adresse de fonction callback. Ca ne doit pas être possible ...
Il faudrait pouvoir donner dynamiquement l'adresse de la fonction
Si par « dynamiquement » tu entends « à l'exécution », c'est bien le cas.
Oui c'est ce que je voulais dire.
Mon idée était mauvaise, je pensais pouvoir convertir l'adresse d'une fonction membre en une adresse de fonction callback. Ca ne doit pas être possible ...
drkm
"Eric Bart" writes:
Mon idée était mauvaise, je pensais pouvoir convertir l'adresse d'une fonction membre en une adresse de fonction callback. Ca ne doit pas être possible ...
Recherche dans les archives du groupe après quelque chose comme "extern C callbak foncteur", tu devrais trouver pas mal de solutions. C'est une question récurrente.
L'idée est que si le pointeur sur fonction doit pointer sur une fonction extern "C", on n'a pas le choix, on doit créer une fonction de ce type. Mais elle peut s'arranger pour déléguer à une classe (fonction membre statique) ou un objet (fonction membre d'instance).
Souvent, les fonctions acceptant des callbacks C acceptent également un pointeur sur void. On passe alors l'adresse d'un objet. La fonction destinée à être enregistrée caste alors son argument vers le type ad-hoc, et appelle la fonction membre ad-hoc de cette objet.
--drkm, en recherche d'un stage : http://www.fgeorges.org/ipl/stage.html
Mon idée était mauvaise, je pensais pouvoir convertir l'adresse
d'une fonction membre en une adresse de fonction callback. Ca ne
doit pas être possible ...
Recherche dans les archives du groupe après quelque chose comme
"extern C callbak foncteur", tu devrais trouver pas mal de solutions.
C'est une question récurrente.
L'idée est que si le pointeur sur fonction doit pointer sur une
fonction extern "C", on n'a pas le choix, on doit créer une fonction
de ce type. Mais elle peut s'arranger pour déléguer à une classe
(fonction membre statique) ou un objet (fonction membre d'instance).
Souvent, les fonctions acceptant des callbacks C acceptent également
un pointeur sur void. On passe alors l'adresse d'un objet. La
fonction destinée à être enregistrée caste alors son argument vers le
type ad-hoc, et appelle la fonction membre ad-hoc de cette objet.
--drkm, en recherche d'un stage : http://www.fgeorges.org/ipl/stage.html
Mon idée était mauvaise, je pensais pouvoir convertir l'adresse d'une fonction membre en une adresse de fonction callback. Ca ne doit pas être possible ...
Recherche dans les archives du groupe après quelque chose comme "extern C callbak foncteur", tu devrais trouver pas mal de solutions. C'est une question récurrente.
L'idée est que si le pointeur sur fonction doit pointer sur une fonction extern "C", on n'a pas le choix, on doit créer une fonction de ce type. Mais elle peut s'arranger pour déléguer à une classe (fonction membre statique) ou un objet (fonction membre d'instance).
Souvent, les fonctions acceptant des callbacks C acceptent également un pointeur sur void. On passe alors l'adresse d'un objet. La fonction destinée à être enregistrée caste alors son argument vers le type ad-hoc, et appelle la fonction membre ad-hoc de cette objet.
--drkm, en recherche d'un stage : http://www.fgeorges.org/ipl/stage.html
kanze
Falk Tannhäuser wrote in message news:<cgkrae$p73$...
Loïc Joly wrote:
Eric Bart wrote:
J'aimerais utiliser une fonction membre d'une classe comme une fonction callback.
Par exemple pour utiliser une thread : pthread_create (&th, NULL, MaClasse::MaFonction, NULL);
Si MaFonction est déclarée en static, ça fonctionne.
Même ça n'est pas garanti, car à mon avis, pthread_create nécessite comme argument un pointeur sur une fonction qualifiée 'extern "C"'.
Tout à fait.
Les fonctions C++ et C ne sont pas forcement interchangeables entre elles, non seulement à cause du "name mangling" (qui n'intervient pas lorsque l'appel se fait par pointeur) mais aussi parce que la "calling convention" (Passage des paramètres dans des registres ou sur la pile ? Dans quel ordre ? Qui fait le ménage sur la pile au retour - la fonction appelée ou la fonction appelante ? Comment passer la valeur de retour ?) peut différer entre les deux langages. Certains compilateurs (par exemple GCC) acceptent la conversion sans problème (soit ils utilisent la même convention d'appel, soit ils génèrent un bout de code faisant les conversions nécessaires s'il en y a besoin) mais cela reste non portable.
Accepter le code, c'est une extension non conforme, parce que la norme exige un diagnostique dans ce cas-ci.
(À mon avis, ça serait *Bien* si une nouvelle release de la Norme C++ mandatait un comportement satisfaisant dans tous les cas...)
Le problème, c'est que la norme C++ ne peut pas imposer des contraints sur le C. Le but de l'« extern "Langage" », c'est justement de dire au compilateur qu'il faut utiliser d'autres conventions. Je ne vois pas comment la norme C++ pourrait imposer que les conventions soient les même en C et en C++ -- il ne peut qu'imposer les contraints sur le C++.
Dans la pratique, il faut dire aussi qu'il y a eu des implémentations où les conventions C et C++ différaient. Ce n'est donc pas qu'une considération théorique.
-- James Kanze GABI Software http://www.gabi-soft.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
Falk Tannhäuser <falk.tannhauser@crf.canon.fr> wrote in message
news:<cgkrae$p73$1@s5.feed.news.oleane.net>...
Loïc Joly wrote:
Eric Bart wrote:
J'aimerais utiliser une fonction membre d'une classe comme une
fonction callback.
Par exemple pour utiliser une thread :
pthread_create (&th, NULL, MaClasse::MaFonction, NULL);
Si MaFonction est déclarée en static, ça fonctionne.
Même ça n'est pas garanti, car à mon avis, pthread_create nécessite
comme argument un pointeur sur une fonction qualifiée 'extern "C"'.
Tout à fait.
Les fonctions C++ et C ne sont pas forcement interchangeables entre
elles, non seulement à cause du "name mangling" (qui n'intervient pas
lorsque l'appel se fait par pointeur) mais aussi parce que la "calling
convention" (Passage des paramètres dans des registres ou sur la pile
? Dans quel ordre ? Qui fait le ménage sur la pile au retour - la
fonction appelée ou la fonction appelante ? Comment passer la valeur
de retour ?) peut différer entre les deux langages. Certains
compilateurs (par exemple GCC) acceptent la conversion sans problème
(soit ils utilisent la même convention d'appel, soit ils génèrent un
bout de code faisant les conversions nécessaires s'il en y a besoin)
mais cela reste non portable.
Accepter le code, c'est une extension non conforme, parce que la norme
exige un diagnostique dans ce cas-ci.
(À mon avis, ça serait *Bien* si une nouvelle release de la Norme C++
mandatait un comportement satisfaisant dans tous les cas...)
Le problème, c'est que la norme C++ ne peut pas imposer des contraints
sur le C. Le but de l'« extern "Langage" », c'est justement de dire au
compilateur qu'il faut utiliser d'autres conventions. Je ne vois pas
comment la norme C++ pourrait imposer que les conventions soient les
même en C et en C++ -- il ne peut qu'imposer les contraints sur le C++.
Dans la pratique, il faut dire aussi qu'il y a eu des implémentations où
les conventions C et C++ différaient. Ce n'est donc pas qu'une
considération théorique.
--
James Kanze GABI Software http://www.gabi-soft.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
Falk Tannhäuser wrote in message news:<cgkrae$p73$...
Loïc Joly wrote:
Eric Bart wrote:
J'aimerais utiliser une fonction membre d'une classe comme une fonction callback.
Par exemple pour utiliser une thread : pthread_create (&th, NULL, MaClasse::MaFonction, NULL);
Si MaFonction est déclarée en static, ça fonctionne.
Même ça n'est pas garanti, car à mon avis, pthread_create nécessite comme argument un pointeur sur une fonction qualifiée 'extern "C"'.
Tout à fait.
Les fonctions C++ et C ne sont pas forcement interchangeables entre elles, non seulement à cause du "name mangling" (qui n'intervient pas lorsque l'appel se fait par pointeur) mais aussi parce que la "calling convention" (Passage des paramètres dans des registres ou sur la pile ? Dans quel ordre ? Qui fait le ménage sur la pile au retour - la fonction appelée ou la fonction appelante ? Comment passer la valeur de retour ?) peut différer entre les deux langages. Certains compilateurs (par exemple GCC) acceptent la conversion sans problème (soit ils utilisent la même convention d'appel, soit ils génèrent un bout de code faisant les conversions nécessaires s'il en y a besoin) mais cela reste non portable.
Accepter le code, c'est une extension non conforme, parce que la norme exige un diagnostique dans ce cas-ci.
(À mon avis, ça serait *Bien* si une nouvelle release de la Norme C++ mandatait un comportement satisfaisant dans tous les cas...)
Le problème, c'est que la norme C++ ne peut pas imposer des contraints sur le C. Le but de l'« extern "Langage" », c'est justement de dire au compilateur qu'il faut utiliser d'autres conventions. Je ne vois pas comment la norme C++ pourrait imposer que les conventions soient les même en C et en C++ -- il ne peut qu'imposer les contraints sur le C++.
Dans la pratique, il faut dire aussi qu'il y a eu des implémentations où les conventions C et C++ différaient. Ce n'est donc pas qu'une considération théorique.
-- James Kanze GABI Software http://www.gabi-soft.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
kanze
"Eric Bart" wrote in message news:<412ddfc3$0$23228$...
J'aimerais utiliser une fonction membre d'une classe comme une fonction callback.
Par exemple pour utiliser une thread : pthread_create (&th, NULL, MaClasse::MaFonction, NULL);
Si MaFonction est déclarée en static, ça fonctionne.
Mais est-ce possible avec une fonction membre non statique ?
Ce n'est pas possible avec une fonction membre, statique ou non. Il faut que ce soit une fonction libre déclarée « extern "C" ».
Il faudrait pouvoir donner dynamiquement l'adresse de la fonction ... non ?
Il faut en prendre l'adresse, parce que c'est l'adresse d'une fonction qu'attend pthread_create. Mais où en est le problème :
extern "C" void* threadStarter( void* p ) { return static_cast< MaClass* >( p )->maFonction() ; }
Tiens, une question pour les experts : est-ce qu'une fonction templatée puisse être « extern "C" » ? Parce que je verais bien un template pour « threadStarter », ci-dessus.
-- James Kanze GABI Software http://www.gabi-soft.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
"Eric Bart" <eb-adm@eric-bart.pasdepubmerci.net> wrote in message
news:<412ddfc3$0$23228$636a15ce@news.free.fr>...
J'aimerais utiliser une fonction membre d'une classe comme une
fonction callback.
Par exemple pour utiliser une thread :
pthread_create (&th, NULL, MaClasse::MaFonction, NULL);
Si MaFonction est déclarée en static, ça fonctionne.
Mais est-ce possible avec une fonction membre non statique ?
Ce n'est pas possible avec une fonction membre, statique ou non. Il faut
que ce soit une fonction libre déclarée « extern "C" ».
Il faudrait pouvoir donner dynamiquement l'adresse de la fonction ...
non ?
Il faut en prendre l'adresse, parce que c'est l'adresse d'une fonction
qu'attend pthread_create. Mais où en est le problème :
extern "C"
void*
threadStarter( void* p )
{
return static_cast< MaClass* >( p )->maFonction() ;
}
Tiens, une question pour les experts : est-ce qu'une fonction templatée
puisse être « extern "C" » ? Parce que je verais bien un template pour
« threadStarter », ci-dessus.
--
James Kanze GABI Software http://www.gabi-soft.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
Tiens, une question pour les experts : est-ce qu'une fonction templatée puisse être « extern "C" » ? Parce que je verais bien un template pour « threadStarter », ci-dessus.
-- James Kanze GABI Software http://www.gabi-soft.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
Jean-Marc Bourguet
writes:
Tiens, une question pour les experts : est-ce qu'une fonction templatée puisse être « extern "C" » ? Parce que je verais bien un template pour « threadStarter », ci-dessus.
como refuse, mais je n'ai pas fait une recherche dans la norme.
A+
-- Jean-Marc FAQ de fclc++: http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ C++ FAQ Lite en VF: http://www.ifrance.com/jlecomte/c++/c++-faq-lite/index.html Site de usenet-fr: http://www.usenet-fr.news.eu.org
kanze@gabi-soft.fr writes:
Tiens, une question pour les experts : est-ce qu'une fonction templatée
puisse être « extern "C" » ? Parce que je verais bien un template pour
« threadStarter », ci-dessus.
como refuse, mais je n'ai pas fait une recherche dans la norme.
A+
--
Jean-Marc
FAQ de fclc++: http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ
C++ FAQ Lite en VF: http://www.ifrance.com/jlecomte/c++/c++-faq-lite/index.html
Site de usenet-fr: http://www.usenet-fr.news.eu.org
Tiens, une question pour les experts : est-ce qu'une fonction templatée puisse être « extern "C" » ? Parce que je verais bien un template pour « threadStarter », ci-dessus.
como refuse, mais je n'ai pas fait une recherche dans la norme.
A+
-- Jean-Marc FAQ de fclc++: http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ C++ FAQ Lite en VF: http://www.ifrance.com/jlecomte/c++/c++-faq-lite/index.html Site de usenet-fr: http://www.usenet-fr.news.eu.org
Falk Tannhäuser
wrote:
Tiens, une question pour les experts : est-ce qu'une fonction templatée puisse être « extern "C" » ? Parce que je verais bien un template pour « threadStarter », ci-dessus.
est accepté par g++, ainsi que Comeau et Dinkum en ligne (je sais que cela ne constitue pas une preuve...)
Avec g++, cela me permet de faire _____________________________________________________ #include <iostream> #include <ostream> #include <pthread.h> #include <cassert>
On pourrait certainement faire quelque chose de plus balèze, prenant un pointeur sur la fonction membre en paramètre, puis qui encapsule aussi l'appel à pthread_create, de manière à empêcher que quelqu'un passe un pointeur sur un type incompatible comme quatrième argument ...
Falk Falk
kanze@gabi-soft.fr wrote:
Tiens, une question pour les experts : est-ce qu'une fonction templatée
puisse être « extern "C" » ? Parce que je verais bien un template pour
« threadStarter », ci-dessus.
est accepté par g++, ainsi que Comeau et Dinkum en ligne (je sais que cela
ne constitue pas une preuve...)
Avec g++, cela me permet de faire
_____________________________________________________
#include <iostream>
#include <ostream>
#include <pthread.h>
#include <cassert>
On pourrait certainement faire quelque chose de plus balèze,
prenant un pointeur sur la fonction membre en paramètre,
puis qui encapsule aussi l'appel à pthread_create, de manière
à empêcher que quelqu'un passe un pointeur sur un type incompatible
comme quatrième argument ...
Tiens, une question pour les experts : est-ce qu'une fonction templatée puisse être « extern "C" » ? Parce que je verais bien un template pour « threadStarter », ci-dessus.
est accepté par g++, ainsi que Comeau et Dinkum en ligne (je sais que cela ne constitue pas une preuve...)
Avec g++, cela me permet de faire _____________________________________________________ #include <iostream> #include <ostream> #include <pthread.h> #include <cassert>
On pourrait certainement faire quelque chose de plus balèze, prenant un pointeur sur la fonction membre en paramètre, puis qui encapsule aussi l'appel à pthread_create, de manière à empêcher que quelqu'un passe un pointeur sur un type incompatible comme quatrième argument ...