El Rabou
Messages postés4Date d'inscriptionjeudi 16 décembre 2004StatutMembreDernière intervention17 mai 2005
-
17 mai 2005 à 11:43
vecchio56
Messages postés6535Date d'inscriptionlundi 16 décembre 2002StatutMembreDernière intervention22 août 2010
-
17 mai 2005 à 17:18
Bonjour
je cherche a faire un thread qui soit une méthode d'un objet celle-ci étant non statique.
Le tout en Visual C++ 6. Bien sûr j'ai trouvé l'astuce de passer la fenêtre en paramètre au thread, mais cela ne me satisfait pas pour des raisons de design UML.
J'utilise actuellement CreateThread( ) pour créer le thread ce n'est peut etre de la que vient le problème (CreateThread n'accepte que les méthodes statiques ? ) .
Je suis preneur de toute suggestion.
Merci
C'est le manque de foi qui rend fous les hommes...
cs_Arnotic
Messages postés933Date d'inscriptiondimanche 1 avril 2001StatutMembreDernière intervention 9 janvier 2012 17 mai 2005 à 11:51
Comment veux-tu créer un thread sur une fonction qui n'a pas d'adresse mémoire fixe (donc non statique) ?
C'est physiquement impossible. Donc il faut que ce soit une fonction statique tout comme pour les callbacks.
vecchio56
Messages postés6535Date d'inscriptionlundi 16 décembre 2002StatutMembreDernière intervention22 août 201014 17 mai 2005 à 12:01
En ce qui me concerne j'ai du mal à comprendre pourquoi ca ne marche
pas, une méthode étant juste une fonction normal prenant en plus en
paramètre (implicite) un objet. Cela a-t-il un rapport avec l'héritage
et les méthodes virtuelles?
ymca2003
Messages postés2070Date d'inscriptionmardi 22 avril 2003StatutMembreDernière intervention 3 juillet 20067 17 mai 2005 à 12:19
Justement ce paramètres implicite empêche les callback d'être appelées car il faut fournir le pointeur this que l'API Win32 est incapable de deviner lors de l'appel à la fonction CALLBACK. Le seul moyen serait de lui fournir en paramètre ce pointeur ce qui est tout de même possible car en général on peut fournir un param en plus de la CALLBACK que le prog peut reconvertir en pointeur sur l'objet. La CALLBACK peut ensuite appeler une fonction membre. Il faut obligatoirement passer par cette étape...
cs_Arnotic
Messages postés933Date d'inscriptiondimanche 1 avril 2001StatutMembreDernière intervention 9 janvier 2012 17 mai 2005 à 12:31
Pour créer une callback ou un thread il te faut une adresse mémoire fixe pour une fonction à la compilation. Hors en C++ avec les class tu n'as plus ca. Donc tu es obligé de définir statique si tu veux en avoir un.
@+
Arnotic,
Admin CS, MVP Visual C++
Vous n’avez pas trouvé la réponse que vous recherchez ?
cosmobob
Messages postés700Date d'inscriptionmardi 30 décembre 2003StatutMembreDernière intervention27 janvier 20094 17 mai 2005 à 14:17
salut,
Arnotic: une methode non statique d'une classe a une adresse fixe (sauf
si la fonction est virtuelle). Le truc c'est qu'une methode non
statique recoit en plus implicitement la valeur du pointeur this (qui
est passé a travers ecx ou edx d'ailleurs).
El Rabou: Cree une fonction static de la forme la:
class test
{
static int functhread(test* param)
{
if (!param)
return 0;
test& theObject = *param;
// mtnt theObject designe l'objet que tu avais créé
// etc...
return 1;
}
si ton design uml foire, c'est que il y a quelque chose de mal
concu.... de toute facons faire ceci est perilleux car entre temps;
theObject peut ne plus exister dans le thread principal ou il a été
créé... donc dans ton diagramme il faut bien s'assurer que sa durée de
vie est plus grande que celle du thread (peut etre est-ce un singleton,
et qu'il dure pdt tout le prog ?)
El Rabou
Messages postés4Date d'inscriptionjeudi 16 décembre 2004StatutMembreDernière intervention17 mai 2005 17 mai 2005 à 14:20
En faite, il y a plusieurs manieres de compiler la techno objet. Le truc, c que je c pas comment visual c++ si prend. Liste chainer de pointeur de fonctions ? decalage ? si quelqu'un pouvait me dire où je peut trouvé ça ... ça m'aiderait à comprendre se qu'il fait, et donc comment il compile, et donc, bien des erreurs. Je ne l'ai pas vue dans la msdn. C'est pourtant le genre de truc façile à trouvé sur d'autre compilo c++ (je vien du monde de l'info indus... et sur microcontroleurs ces informations sont capital et donc spécifié dans les doc)
Merci de votre aide.
C'est le manque de foi qui rend fous les hommes...
ymca2003
Messages postés2070Date d'inscriptionmardi 22 avril 2003StatutMembreDernière intervention 3 juillet 20067 17 mai 2005 à 14:34
Les méhodes non statiques des classes ont bien une adresse fixée à l'édition de lien (il suffit de générer le .map pour le voir).
Le compilo passe simplement un pointeur sur l'objet appelant en param supplémentaire de la méthodes (dans le registre ecx pour x86).
Pour les méthodes non virtuelles on appelle donc simplement la méthode comme n'importe quelle autre fonction.
Pour les méthodes virtuelles c'est différent. Chaque classe ayant au moins une méthode virtuelle possède une table contenant l'addresse des fonctions virtuelles. Cette table est initialisée à la construction de l'objet en fonction de sa véritable classe.
Ainsi 2 objets de 2 classes différentes mais dérivant d'une même classe auront des implémentations différentes pour une méthode virtuelle mais cette méthode sera accessible par le même indice dans la table. Tout ça c'est le compilo qui s'en charge.
Les implémentations des méthodes virtuelles ont bien sûr une addresse fixe connue à l'édition de lien. Cette addresse est mise dans la vtable lors de la construction de l'objet. C'est juste au momemt de l'appel que le compilo passe par la table virtuelle pour récupéper l'adresse de la fonction correspondante à la classe du Runtime. plutot que d'appeler directement la fonction.
cosmobob
Messages postés700Date d'inscriptionmardi 30 décembre 2003StatutMembreDernière intervention27 janvier 20094 17 mai 2005 à 14:48
j'ai pas bien pigé ta question mais j'essaie d'y repondre :)
si tu passes une fonction non statique comme parametre d'un thread, pourquoi cela ne compile t'il pas?
tout simplement parce que la convention d'appel de ta methode non
statique de ta classe n'est pas la meme que celle d'une fonction
'classique'. Les parametres de la fonction/methode sont bien mis sur la
pile, mais dans le cas d'un appel d'une fonction membre non statique,
le compilateur (vc 6 du moins) stocke dans edx la valeur du
pointeur this, puis appelle la methode "normalement".
en gros si tu ecris ceci:
class test
{
private:
std::string message;
public:
void SetMessage(const char* nvomessage)
{
message = nvomessage;
}
}
test ObjetTest;
ObjetTest.SetMessage( "salut !");
que se passe t'il a ce moment?
pour appeler SetMessage, le compilo place l'adresse de ObjetTest dans
edx, puis il empile l'adresse de la chaine "salut !" sur la pile, et la
il appelle la fonction SetMessage.
A l'interieur de cette fonction, le compilo peut connaitre l'adresse du
std::string message de l'objet ObjetTest, car celui ci se retrouve
facilement a partir de l'adresse de this qui est contenue dans edx (il
est par exemple a l'adresse edx, ou edx+4, ou ... tout depend de
l'existence ou non d'autres champs dans la classe)
Mais maintenant si j'ai une fonction quelconque:
void DireBonjour(const char* msg)
{
std::cout << "bonjour : " << msg << endl;
}
Pour appeler cette fonction, pas besoin de remplir edx... c'est pas une fonction membre d'une classe.
Si tu appelles CreateThread, le compilo t'empeche de passer une
fonction non statique, car CreateThread ne va pa toucher a edx qui doit
pourtant imperativement contenir le pointeur this avant l'appel d'une
fonction membre non statique. Il n'y touche pas, car d'habitude il n'y
a pas besoin d'y toucher ...
tu peux feinter en faisant ca:
class test
{
static int functhread(test* param)
{
if (!param)
return 0;
test& theObject = *param;
// mtnt theObject designe l'objet que tu avais créé
theObject.AppelFuncThreadNonStatique();
// etc...
return 1;
}
void AppelFuncThreadNonStatique(void)
{
// ce que tu veux ... c 'est pas ici une fonction statique
cosmobob
Messages postés700Date d'inscriptionmardi 30 décembre 2003StatutMembreDernière intervention27 janvier 20094 17 mai 2005 à 14:50
bon ben ymca m'infirme en me disant que c'est dans ecx qu'est passé le
pointeur this ... pour avoir déja regardé, je savais que c'etait l'un
des deux, mais plus lequel exactement .... donc dans ce que j'ai dit
remplacer edx par ecx (c'est assez peu important)
cs_Arnotic
Messages postés933Date d'inscriptiondimanche 1 avril 2001StatutMembreDernière intervention 9 janvier 2012 17 mai 2005 à 14:52
Pour notre problème il faut que notre code de la fonction soit chargée en mémoire pendant toute l'éxecution du programme à la même adresse sans aucun changement.
Dans ce que tu viens d'énoncer avant, tu te perds dans tes explications. Relis tes premières phrases.
ymca2003
Messages postés2070Date d'inscriptionmardi 22 avril 2003StatutMembreDernière intervention 3 juillet 20067 17 mai 2005 à 14:58
Arnotic -> qui se perd dans ses explications (moi ou Cosmobob) ?
Parce que que cela soit du C ou du C++ le code ne change pas d'addresse en cours de route, une fois qu'une fonction est chargée à un endroit en mémoire elle n'y bouge plus et donc on peut passer son addresse à une autre fonction. Les fonctions de CALLBACK marche également avec le C++ à condition que la classe soit spécifiée dans la signature de la fonction et que la fonction qui va appelée notre CALLBACK fournisse l'objet (c'est comme cela que marche les MFC et le routage des messages).
Donc je maintiens que le problème avec les CALLBACK des API Win32 c'est pas l'adresse mais le pointeur this.
cs_Arnotic
Messages postés933Date d'inscriptiondimanche 1 avril 2001StatutMembreDernière intervention 9 janvier 2012 17 mai 2005 à 14:59
c'est peu important edx ou ecx ?????
faut vraiment arrêter les gamineries à un moment. lisez un bon bouquin sur les processeurs et l'assembleur x86 avant de vous lancer dans des débats de ce type.
une adresse mémoire est codée sur 4 octets et elle pointe directement sur du code placée en mémoire. or si on ne déclare pas en statique nous n'ravons pas cette adresse mémoire de connues directement.
cs_Arnotic
Messages postés933Date d'inscriptiondimanche 1 avril 2001StatutMembreDernière intervention 9 janvier 2012 17 mai 2005 à 15:05
C et C++ rien à voir
C = language non objet
C++ = language orienté programmation objet
pointeur this, et compagnie purement virtuel.
en assembleur pour la callback on veut simplement savoir l'adresse directe de la fonction.
hors si on déclare pas en statique on ne peut pas l'avoir.
vecchio56
Messages postés6535Date d'inscriptionlundi 16 décembre 2002StatutMembreDernière intervention22 août 201014 17 mai 2005 à 15:08
Arnotic, j'ai pas voulu lancer un débat, j'ai juste demandé à
comprendre un truc que j'ai jamais compris, et pour l'instant ce n'est
pas toi qui donne le plus d'explications.
Pourquoi dis-tu qu'on ne connait pas l'adresse d'une méthode non-static?