Probleme threads

Résolu
turnerom Messages postés 492 Date d'inscription samedi 10 juillet 2004 Statut Membre Dernière intervention 12 janvier 2012 - 9 mai 2006 à 12:01
cs_AlexN Messages postés 694 Date d'inscription lundi 5 décembre 2005 Statut Membre Dernière intervention 8 janvier 2014 - 11 mai 2006 à 15:59
Bonjour,
je n'arrive pas à compiler ce petit programme servant a illustrer mon problème :

<hr size="2" width="100%">#include
#include

using namespace std;

static pthread_mutex_t mutex;

struct Foo
{
string f;
Foo();
~Foo();
void* affiche(void *p_data);
};

Foo::Foo ()
{
string tmp("Je suis Foo");
f=tmp;
}

Foo::~Foo()
{ }

void* Foo::affiche(void *p_data)
{
cout << f << endl;
return NULL;
}

int main()
{
pthread_mutex_init (&mutex, NULL);

pthread_t thrd1;

Foo f;

pthread_create(&thrd1,NULL,f.affiche,NULL);

pthread_join(thrd1, NULL);

cout << "Fin" << endl;

return 0;
}
<hr size="2" width="100%">
Ce programme ne fait pas grand chose, il sert juste d'illustration au problème que je rencontre.

Pourquoi le compilo me dit-il : fichier.cpp:40: error: argument of type `void*(Foo::)(void*)' does not match `void*(*)(void*)'
Et comment résoudre mon problème.
D'avance merci !

TuRn3r

18 réponses

cs_AlexN Messages postés 694 Date d'inscription lundi 5 décembre 2005 Statut Membre Dernière intervention 8 janvier 2014 19
9 mai 2006 à 16:20
Il s'agit d'un problème de transtypage, mais je ne vois pas trop non plus. pcreate_thread ne semble pas aimer les parametres de type fonction membre ou le transtypage n'est pas écrit correctement.
Il doit y avoir un moyen de forcer mais je ne vois pas. désolé.

essayes ça : c'est pas la bonne solution mais ça compile semble-t-il

void * p (void *t) {
((Foo *)t)->affiche(t);
}

int main()
{
pthread_mutex_init (&mutex, NULL);

pthread_t thrd1;

Foo f;
pthread_create(&thrd1,NULL,p,(void *)&f);

pthread_join(thrd1, NULL);

cout << "Fin" << endl;

return 0;
}

Par contre si quelqu'un comprend son problème je suis aussi preneur !
3
olbal Messages postés 20 Date d'inscription vendredi 16 mai 2003 Statut Membre Dernière intervention 29 septembre 2006
10 mai 2006 à 13:19
[auteurdetail.aspx?ID= 638418 AlexN]-> structure et classe c'est la même chose comme l'a expliqué [auteurdetail.aspx?ID=304809 turnerom] mis à part la valeur par défaut d'accès qui est dans un cas est public et dans l'autre est privé; et une fonction membre ayant pour nom le nom de la structure, est bien un constructeur de la stucture, de même que la structure peut avoir un destructeur, etc...

[auteurdetail.aspx?ID=304809 turnerom]: Concernant l'erreur, elle vient du fait que tu passes l'adresse d'une fonction membre de structure Foo `void*(Foo::)(void*)' alors que la fonction pthread_create attend l'adresse d'un fonction simple `void*(*)(void*)'. En simplifiant pour le compilateur, l'appel d'une fonction membre se fait comme l'appel d'une fonction simple mais avec en plus la transmission d'un paramètre supplémentaire (et caché) qui est le pointeur sur la (structure ou la classe): C'est le fameux 'this'. C'est comme cela que se fait le lien entre les fonctions membre de l'objet et les données de l'objet. Il me semble d'ailleurs que les 1er compilateurs C++ ne permettait pas d'obtenir l'adresse d'une fonction membre, ce qui n'était pas plus mal car l'adresse d'une fonction membre sans l'adresse de l'instance de la classe à laquelle elle appartient n'est pas utilisable sauf en assembleur puisque la on peut rajouter le pointeur (this) sur la pile.

La solution d'[auteurdetail.aspx?ID =638418 AlexN] est donc exacte. On aurait pu parvenir au même résultat, en rendant la fonctions affiche static et la le paramètre void *p_data avait une utilité
3
turnerom Messages postés 492 Date d'inscription samedi 10 juillet 2004 Statut Membre Dernière intervention 12 janvier 2012 1
10 mai 2006 à 13:49
Toute petite précision :
ne pas oublier

void * p (void *t) {
((Foo *)t)->affiche(t);
return NULL;
}

Ca ne sert à rien, je sais, mais ca évite au compilo de gueuler.

TuRn3r
3
turnerom Messages postés 492 Date d'inscription samedi 10 juillet 2004 Statut Membre Dernière intervention 12 janvier 2012 1
11 mai 2006 à 09:14
Sinon,
s'il y a encore un peu de monde dans le coin, voila comment faire beaucoup (!!!) plus simple avec BOOST:

<hr size="2" width="100%">#include
#include

using namespace std;
using namespace boost;

struct Foo
{
string f;
string m_nom;
Foo(const string nom);
~Foo();
void operator()();
};

Foo::Foo (const string nom)
:m_nom(nom)
{
string tmp("Je suis Foo");
f=tmp;
}

Foo::~Foo()
{ }

void Foo::operator()()
{
cout << m_nom << " : " << f << endl;
}

int main()
{
thread thrd1(Foo("Bob"));

thrd1.join();

cout << "Fin" << endl;

return 0;
}

<hr size="2" width="100%">
TuRn3r
3

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

Posez votre question
cs_AlexN Messages postés 694 Date d'inscription lundi 5 décembre 2005 Statut Membre Dernière intervention 8 janvier 2014 19
9 mai 2006 à 12:08
c'est pas class Foo que tu voulais écrire au lieu de struct Foo ?
0
cs_laurent1024 Messages postés 987 Date d'inscription mardi 31 mai 2005 Statut Membre Dernière intervention 30 août 2012 25
9 mai 2006 à 12:08
Peux etre que ca vient du faite que Foo est une structure et pas une classe
++
0
cs_laurent1024 Messages postés 987 Date d'inscription mardi 31 mai 2005 Statut Membre Dernière intervention 30 août 2012 25
9 mai 2006 à 12:10
Excuses pour la répétition, AlexN a ete plus rapide
0
turnerom Messages postés 492 Date d'inscription samedi 10 juillet 2004 Statut Membre Dernière intervention 12 janvier 2012 1
9 mai 2006 à 12:29
Non, ca ne vient pas de la.
Dans mon prog j'ai bien class et j'ai la meme erreur.
De plus une structure n'est jamais qu'une classe ou tout les membres sont publics.

En fait:
struct Foo
{
string f;
Foo();
~Foo();
void* affiche(void *p_data);
};

est absolument equivalent a:
class Foo
{
public :
string f;
Foo();
~Foo();
void* affiche(void *p_data);
};

Mais merci quand meme !

TuRn3r
0
cs_AlexN Messages postés 694 Date d'inscription lundi 5 décembre 2005 Statut Membre Dernière intervention 8 janvier 2014 19
9 mai 2006 à 12:50
Hum si les structures c'etaient stricto senso la même chose qu'une classe, personne les aurais inventé.

Ok syntaxiquement ça se ressemble. Mais les traitements et les propriétés d'une structure et d'une classe sont très très différents...Entre autres, ta fonction Foo() pour la structure est juste une fonction, tandis que pour la classe Foo c'est un constructeur.

En ce qui concerne les structure auto reférentes, il faut toujours faire préceder la définition de la structure par une declaration du type pointeur sur struct. Tu ne peux pas declarer la classe Foo, avant de l'avoir défini. Le compilateur ne connait pas la taille avant la definition. Il ne connait que la taille d'un pointeur.
0
turnerom Messages postés 492 Date d'inscription samedi 10 juillet 2004 Statut Membre Dernière intervention 12 janvier 2012 1
9 mai 2006 à 13:53
Admetons!
dans le cas suivant alors, d'ou peut provenir l'erreur svp ?
<hr size="2" width="100%">#include
#include

using namespace std;

static pthread_mutex_t mutex;

class Foo
{
public:
string f;
Foo();
~Foo();
void* affiche(void *p_data);
};

Foo::Foo ()
{
string tmp("Je suis Foo");
f=tmp;
}

Foo::~Foo()
{ }

void* Foo::affiche(void *p_data)
{
cout << f << endl;
return NULL;
}

int main()
{
pthread_mutex_init (&mutex, NULL);

pthread_t thrd1;

Foo f;

pthread_create(&thrd1,NULL,f.affiche,NULL);

pthread_join(thrd1, NULL);

cout << "Fin" << endl;

return 0;
}
<hr size="2" width="100%">
Pourquoi le compilo me dit-il : fichier.cpp:40: error: argument of type `void*(Foo::)(void*)' does not match `void*(*)(void*)'
Et comment résoudre mon problème.
D'avance merci !

TuRn3r
0
cs_AlexN Messages postés 694 Date d'inscription lundi 5 décembre 2005 Statut Membre Dernière intervention 8 janvier 2014 19
9 mai 2006 à 14:45
Ligne 40 c'est laquelle ?
vient du parametre de pthread_create() ? Le compilateur semble te dire qu'il attend un paramatère de type void*(*)(void*).
tentes un cast void*(*)(void*) sur le paramètre f.affiche()
0
turnerom Messages postés 492 Date d'inscription samedi 10 juillet 2004 Statut Membre Dernière intervention 12 janvier 2012 1
9 mai 2006 à 14:55
Non, je viens d'essayer, pas mieu.

La ligne 40, qui pose problème est celle-la:
pthread_create(&thrd1,NULL,f.affiche,NULL);

TuRn3r
0
cs_AlexN Messages postés 694 Date d'inscription lundi 5 décembre 2005 Statut Membre Dernière intervention 8 janvier 2014 19
10 mai 2006 à 13:30
Merci pour ces précisions

Bonne journée
0
turnerom Messages postés 492 Date d'inscription samedi 10 juillet 2004 Statut Membre Dernière intervention 12 janvier 2012 1
10 mai 2006 à 13:45
Idemement !

Merci à tous

TuRn3r
0
cs_AlexN Messages postés 694 Date d'inscription lundi 5 décembre 2005 Statut Membre Dernière intervention 8 janvier 2014 19
10 mai 2006 à 13:53
Juste un truc,

Je ne penses pas qu'une structure puisse être dérivée, ni que ses fonction membres puisse être surchargées ou virtualisées. Ni même que tous les mécanismes liés aux classes/objets (en dehors de la construction et destruction) pouvaient être applicables aux structures. Et j'ai quand même un doute.

Notemment je cite : Bjarne Stroustrup "Le langage C++" - Chapitre 5 - Les classes - 5.2.1-5.2.2 :

struct date {
int month, date, year;

void set (int, int, int);
void get (int *, int *, int *);
void next();
void print();
}

"La déclaration de date dans le paragraphe précédent offre un ensemble de fonctions pour la manipuler, mais elle ne précise pas que ces fonctions peuvent être les seules à pouvoir accéder aux objets de type date. Cette restriction peut être exprimée en utilisant une classe au lieu d'une struct : "

class date {
int month, date, year;

public:

void set (int, int, int);

void get (int *, int *, int *);

void next();

void print();

}

Le fait de distinguer struct et class par deux mots reservés implique que les mécanismes mis en jeu ne sont pas identiques. Sinon c'est de la redondance.

Je me trompe ?
0
turnerom Messages postés 492 Date d'inscription samedi 10 juillet 2004 Statut Membre Dernière intervention 12 janvier 2012 1
10 mai 2006 à 14:13
La différence se situ dans le fait que dans une struct tout est public et tu ne peux rien mettre en "private" ni "protected".
Alors que dans unje class par défaut tout est privé mais tu peux mettre des choses "public".

Or c'est bien ce qui est dit. Dans

class date {
int month, date, year;
public:
void set (int, int, int);
void get (int *, int *, int *);
void next();
void print();
}

month, date et year étant privé (par défaut) seule des fonctions membres de date pouront y avoir accès comme ici set, get, ....

Alors qu'avec la structure tu peux faire un:
date d;
d.month=11;

Alors qu'avec la class tu te feras jeté, il faudra que tu utilise le "setter" :
date d;
d.set(1,11,2006);

TuRn3r
0
olbal Messages postés 20 Date d'inscription vendredi 16 mai 2003 Statut Membre Dernière intervention 29 septembre 2006
11 mai 2006 à 12:51
[auteurdetail.aspx?ID= 304809 Voir http://c.developpez.com/faq/cpp/?page=classes et plus partuculièrement le paragraphe "]Quelle est la différence entre class et struct ?"





Je pensais que class = struct sans exception, en fait j'ai appris sur cette page qu'il y en avait une si on utilise template.



[auteurdetail.aspx?ID=304809 turnerom]-> Dans une structure les membres sont par défaut public mais rien empêche d'utiliser private ou protected. C'est en C pur que tout les membres sont forcément public mais dans ce cas en ne peut avoir que des membres de type variable, car le concept de fonction membre n'existe pas.

[auteurdetail.aspx?ID =638418 AlexN] -> Tu as écrit :"Le fait de distinguer struct et class par deux mots reservés implique
que les mécanismes mis en jeu ne sont pas identiques. Sinon c'est de la
redondance."
if et goto suffisent pour faire n'importe quel type de boucle pourtant for, while, do...while existent!
0
cs_AlexN Messages postés 694 Date d'inscription lundi 5 décembre 2005 Statut Membre Dernière intervention 8 janvier 2014 19
11 mai 2006 à 15:59
Ok,
J'ai effectivement mal lu, j'ai fait l'erreur de confondre struct c et struct c++.

Merci encore pour cette mise au point.
0
Rejoignez-nous