Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

C++, pointeurs de fonctions, fonctions membres, threads et signaux

39 réponses
Avatar
vincent.lecoq
Je cherche a develloper une petite librairie en C++ sous Linux (et/ou
BSD ).
Elle a besoin des appels systeme signal et pthread_create.
La fonction associee a mon signal est un membre d'une des classes de
ma librairie, elles est appelee en interne par celle ci pour detacher
un process puis restaurer l'environement d'origine. or g++ (et le C++
en general) m'interdisent de passer cette fonction a signal car elle
est du type MaClasse::ma_fonction et comme cette fonction doit se
servir de certaines variables propres a l'instance de la classe
appelante, je ne peux par l'exterioriser ...

Comment faire ?

10 réponses

1 2 3 4
Avatar
Arnaud Debaene
drkm wrote:
Un pointeur vers une fonction membre statique n'est pas de
même type qu'un pointeur vers une fonction libre.


Ah? C'est quoi la différence (d'après la norme) ?

Arnaud

Avatar
Gabriel Dos Reis
"Arnaud Debaene" writes:

| drkm wrote:
| > Un pointeur vers une fonction membre statique n'est pas de
| > même type qu'un pointeur vers une fonction libre.
|
| Ah? C'est quoi la différence (d'après la norme) ?

D'après la norme, la différence est ce que drkm a écrit.
:-)

-- Gaby
Avatar
James Kanze
(LECOQ Vincent) writes:

|> Je cherche a develloper une petite librairie en C++ sous Linux
|> (et/ou BSD ).

|> Elle a besoin des appels systeme signal et pthread_create. La
|> fonction associee a mon signal est un membre d'une des classes de ma
|> librairie, elles est appelee en interne par celle ci pour detacher
|> un process puis restaurer l'environement d'origine. or g++ (et le
|> C++ en general) m'interdisent de passer cette fonction a signal car
|> elle est du type MaClasse::ma_fonction et comme cette fonction doit
|> se servir de certaines variables propres a l'instance de la classe
|> appelante, je ne peux par l'exterioriser ...

|> Comment faire ?

Il y a en fait deux problèmes ici :

- Le premier, c'est celui dont se plaint le compilateur. Tu ne peux
pas passer l'adresse d'une fonction membre comme adresse d'une
fonction libre. Les deux ne s'appelle pas de la même façon (la
fonction membre a besoin d'un objet), et ne peuvent pas être
interchangées. Pour pthread_create, la solution est simple : tu
crées une fonction globale de linkage C qui convertit le void*
qu'il reçoit en pointeur à la classe, et puis tu appelles la
fonction voulu. Pour signal, c'est plus compliqué, étant donné que
tu n'as pas de paramètre supplémentaire, mais voir le deuxième
point.

- Le deuxième, c'est que ce que tu as droit de faire dans un handler
de signal est très, très restreint, et c'est à parier que s'il te
faut une fonction member d'une classe, c'est trop. Puisque tu parle
aussi de pthread_create, je suppose que l'application est
multi-thread. Dans ce cas-là, la bonne réponse, c'est de créer un
thread gestionnaire des signals, et traiter le signal là. Pour les
détails, voir par exemple "Programming with POSIX Threads", de David
Butenhof (et pour des questions ultérieurs, le groupe qui convient
s'appelle fr.comp.os.unix).

--
James Kanze
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
Avatar
James Kanze
drkm writes:

|> Serge Paccalin writes:

|> > class LaClasse
|> > {
|> > static void *StartStatic(void *pUser);
|> > void *Start();
|> > }

|> > void *LaClasse::StartStatic(void *pUser)
|> > {
|> > LaClasse *pThis = (LaClasse *)pUser;
|> > return pThis->Start();
|> > }

|> > void *LaClasse::Start()
|> > {
|> > // ici, ton vrai code utile de thread
|> > }

|> Même s'il s'agit de la solution souvent présentée, et qui devrait
|> fonctionner partout, cela n'est pas garanti par la norme, il me
|> semble.

Non seulement il n'est pas garantie, il est interdit, et un compilateur
conforme est obligé à le réfuser.

--
James Kanze
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
Avatar
James Kanze
"Arnaud Debaene" writes:

|> drkm wrote:
|> > Un pointeur vers une fonction membre statique n'est pas de même
|> > type qu'un pointeur vers une fonction libre.

|> Ah? C'est quoi la différence (d'après la norme) ?

La différence entre une fonction avec linkage "C", et une fonction sans
linkage "C" ? Le problème, c'est qu'il n'y a aucun moyen à spécifier
qu'une fonction membre statique a linkage "C". Et que les conventions de
l'appel d'une fonction "C" et une fonction "C++" ne sont pas forcément
les mêmes. (Historiquement, sur les plateformes Intel, elles étaient
souvent différentes.)

--
James Kanze
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
Avatar
drkm
James Kanze writes:

drkm writes:

|> Même s'il s'agit de la solution souvent présentée, et qui devrait
|> fonctionner partout, cela n'est pas garanti par la norme, il me
|> semble.

Non seulement il n'est pas garantie, il est interdit, et un compilateur
conforme est obligé à le réfuser.


Tu parles bien du passage d'un pointeur vers fonction membre
statique à une fonction acceptant un pointeur vers fonction libre, par
ailleurs de même signature ? Il me semble avoir déjà utilisé une
telle chose, sans avertissement.

--drkm

Avatar
Franck Branjonneau
James Kanze écrivait:

"Arnaud Debaene" writes:

|> drkm wrote:
|> > Un pointeur vers une fonction membre statique n'est pas de même
|> > type qu'un pointeur vers une fonction libre.

|> Ah? C'est quoi la différence (d'après la norme) ?

La différence entre une fonction avec linkage "C", et une fonction sans
linkage "C" ?


Non, la différence entre le *type* d'un pointeur vers une fonction
membre statique et le *type* d'un pointeur vers une fonction libre.
--
Franck Branjonneau

Avatar
vincent.lecoq
(LECOQ Vincent) wrote in message news:...
Je cherche a develloper une petite librairie en C++ sous Linux (et/ou
BSD ).
Elle a besoin des appels systeme signal et pthread_create.
La fonction associee a mon signal est un membre d'une des classes de
ma librairie, elles est appelee en interne par celle ci pour detacher
un process puis restaurer l'environement d'origine. or g++ (et le C++
en general) m'interdisent de passer cette fonction a signal car elle
est du type MaClasse::ma_fonction et comme cette fonction doit se
servir de certaines variables propres a l'instance de la classe
appelante, je ne peux par l'exterioriser ...

Comment faire ?


Merci pour toutes vos reponses, ca compile, mais maintenant j'ai droit
a un beau core dump sur pthread_create ... et pas que sur la fonction
emebre que je voulais appeler, cette fois le prob vient d'ailleur ...

Merci a tous :)

Avatar
kanze
Franck Branjonneau wrote in message
news:...
James Kanze écrivait:
"Arnaud Debaene" writes:
|> drkm wrote:

|> > Un pointeur vers une fonction membre statique n'est pas de
|> > même type qu'un pointeur vers une fonction libre.

|> Ah? C'est quoi la différence (d'après la norme) ?

La différence entre une fonction avec linkage "C", et une fonction
sans linkage "C" ?


Non, la différence entre le *type* d'un pointeur vers une fonction
membre statique et le *type* d'un pointeur vers une fonction libre.


Il n'y en a pas. Qu'est-ce qui te fait penser qu'il y en a ?

Le problème ici, c'est qu'il nous faut une fonction avec linkage "C".
Qui a donc un type différent d'une fonction avec linkage "C++". Et la
seule raison pourquoi on ne peut pas utiliser une fonction membre
statique, c'est qu'il n'y a aucun syntaxe qui permet à lui donner un
linkage "C".

--
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


Avatar
kanze
drkm wrote in message
news:...
James Kanze writes:

drkm writes:

|> Même s'il s'agit de la solution souvent présentée, et qui
|> devrait fonctionner partout, cela n'est pas garanti par la
|> norme, il me semble.

Non seulement il n'est pas garantie, il est interdit, et un
compilateur conforme est obligé à le réfuser.


Tu parles bien du passage d'un pointeur vers fonction membre
statique à une fonction acceptant un pointeur vers fonction libre, par
ailleurs de même signature ?


Je parles du passage d'un pointeur à une fonction à linkage "C++" vers
un pointeur à une fonction à linkage "C". Les types de f et g,
ci-dessous, ne sont pas identiques :

extern "C++" void* f( void* ) ;
extern "C" void* g( void* ) ;

Or, si j'ai quelque part :

extern "C" {
int pthread_create( pthread_t * thread,
pthread_attr_t const * attr,
void* (* start_routine)( void* ),
void* arg ) ;
}

je ne peux lui passer comme troisième paramètre que g, ci-dessus, et non
f.

Il me semble avoir déjà utilisé une telle chose, sans avertissement.


C'est possible. CFront ne faisait pas la distinction. Zortech, en
revanche, oui, puisque la séquence d'appel pour une fonction C++ n'était
pas la même que pour une fonction C. Le comité n'a voulu interdire les
implémentations comme Zortech (qui est quand même l'implémentation la
plus raisonable sur une architecture Intel). Du coup, le linkage fait
partie du type de la fonction.

En revanche, le type d'une fonction membre statique n'est pas celui
d'une fonction membre. Donc, si j'écris :

struct C
{
static void* h( void* ) ;
} ;

&C::h a le même type que f, ci-dessus. Et on peut en servir partout où
on pourrait se servir de f.

Seulement, comme je viens de dire, on ne peut pas passer f à une
fonction extern "C" comme pthread_create. Donc, &C::h non plus.

--
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


1 2 3 4