IdentifiantMot de passe
Loading...
Mot de passe oubli� ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les r�ponses en temps r�el, voter pour les messages, poser vos propres questions et recevoir la newsletter

MFC Discussion :

[MFC] Multithreading, Thread Worker


Sujet :

MFC

  1. #1
    Membre confirm�
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    150
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2006
    Messages : 150
    Par d�faut [MFC] Multithreading, Thread Worker
    Bonjour,

    J'ai un probl�me avec le multithreading MFC, je voudrai qu'un thread externe � ma boite de dialogue puisse appeler des fonctions de cette boite de dialogue.

    En faites je voudrai que ma boite de dialogue lance un thread worker qui puisse afficher des informations via la boite de dialogue dans un simple label par exemple, pour cela il y a une m�thode publique Echo(char *texte) dans ma boite de dialogue qui permet d'afficher du texte.

    CTestDlg est compos� d'une classe Clol, lorsque j'appuie sur le bouton ok, Clol lance un thread qui va afficher quelque chose dans un label de CTestDlg toutes les secondes en appelant la fonction Echo, j'ai utilis� le handle de la boite de dialogue et utilis� la fonction FromHandle() pour r�cup�rer CTestDlg dans le thread externe mais ca ne fonctionne pas, ca plante dans la fonction Echo() de CTestDlg, au niveau de la ligne loltexte.SetString(buff) :
    Exception non g�r�e � 0x7832c55f (mfc80ud.dll) dans Test.exe : 0xC0000005: Violation d'acc�s lors de la lecture de l'emplacement 0xf3d030fd.

    lol.cpp
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
     
    #include "stdafx.h"
    #include "lol.h"
    #include "TestDlg.h"
     
    HWND Clol::hwnd = 0;
     
    void Clol::Start(){
    	AfxBeginThread(Clol::Thread,NULL);
    }
     
    UINT Clol::Thread(LPVOID param){
    	char text[20];
     
    	CTestDlg* la = (CTestDlg*)CWnd::FromHandle(Clol::hwnd);
     
    	for(int i=0;i<10;i++){
    		sprintf(text,"Ok%d",i);
    		la->Echo(text);
    		Sleep(1000);
    	}
     
    	return 0;
    }
    CTestDlg.h
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    #include "lol.h"
    // boîte de dialogue CTestDlg
    class CTestDlg : public CDialog
    {
    [...]
    public:
            Clol a;
    	CString loltexte;
    	void Echo(char * txt);
    [...]
    CTestDlg.cpp
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    [...]
    
    void CTestDlg::Echo(char * texte){
    	wchar_t buff[500];
    	mbstowcs(buff,texte,500);
            //Ca plante ici
    	loltexte.SetString(buff);
    	UpdateData(false);
    }
    
    
    void CTestDlg::OnBnClickedOk()
    {
    	a.hwnd = GetSafeHwnd();
    	a.Start();
    }
    [...]

    EDIT: Je ne peux pas passer par le syst�me des messages, ca fonctionne tr�s bien mais je ne peux pas utiliser cette m�thode car dans le cas r�el de mon probl�me (ici il s'agit d'une version simplifi�), Echo retourne une valeur que je dois r�cup�rer.

  2. #2
    Expert �minent
    Avatar de M�dinoc
    Homme Profil pro
    D�veloppeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 397
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    �ge : 41
    Localisation : France

    Informations professionnelles :
    Activit� : D�veloppeur informatique
    Secteur : High Tech - �diteur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 397
    Par d�faut
    C'est pourtant simple:
    Code C++ : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    void Clol::Start(CTestDlg *pDlg) {
    	AfxBeginThread(Clol::Thread, pDlg);
    }
     
    UINT Clol::Thread(LPVOID param) {
    	char text[20];
     
    	CTestDlg * la = static_cast< CTestDlg* >(param);
     
    	for(int i=0;i<10;i++){
    		sprintf(text,"Ok%d",i);
    		la->Echo(text);
    		Sleep(1000);
    	}
     
    	return 0;
    }
    Pourquoi se compliquer la vie avec des FromHandle() et des variables globales/statiques quand on peut juste passer un param�tre au thread ?

    Edit: Le syst�me des messages permet �galement de retourner une valeur si on utilise SendMessage(). Et Windows se charge de la synchronisation pour toi...
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parl� avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  3. #3
    Membre confirm�
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    150
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2006
    Messages : 150
    Par d�faut
    Pourquoi faire compliquer ? Car j'ai lu ca : http://msdn2.microsoft.com/fr-fr/lib...2e(VS.80).aspx

    Si on proc�de � ta facon ca plante d'une mani�re diff�rente, on a le droit � un avertissement qui nous dit d'utiliser les handle, puis FromHandle() et non les adresses des objets , j'avais proc�d� de cette mani�re pour commencer, apr�s j'ai appris qu'il fallait le faire a partir des handles.


    EDIT :
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
     
    		ASSERT((CWnd*)p == this);   // must be us
     
    		// Note: if either of the above asserts fire and you are
    		// writing a multithreaded application, it is likely that
    		// you have passed a C++ object from one thread to another
    		// and have used that object in a way that was not intended.
    		// (only simple inline wrapper functions should be used)
    		//
    		// In general, CWnd objects should be passed by HWND from
    		// one thread to another.  The receiving thread can wrap
    		// the HWND with a CWnd object by using CWnd::FromHandle.
    		//
    		// It is dangerous to pass C++ objects from one thread to
    		// another, unless the objects are designed to be used in
    		// such a manner.

  4. #4
    Expert �minent
    Avatar de M�dinoc
    Homme Profil pro
    D�veloppeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 397
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    �ge : 41
    Localisation : France

    Informations professionnelles :
    Activit� : D�veloppeur informatique
    Secteur : High Tech - �diteur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 397
    Par d�faut
    Ceci n'a aucun effet, car la carte des objets CWnd vers HWND est locale pour le thread principal
    C'est absurde! Il n'y a pas de carte CWnd--> HWND, puisque la CWnd CONTIENT le HWND correspondant. Une carte HWND vers CWnd je comprendrais, mais l� on n'est pas cens� en avoir besoin...

    Si on proc�de � ta facon ca plante d'une mani�re diff�rente, on a le droit � un avertissement qui nous dit d'utiliser les handle, puis FromHandle() et non les adresses des objets
    Tu veux dire, une erreur d'assertion ?

    Edit: OK, j'ai compris. La classe CWnd v�rifie un truc dont on n'a pas besoin...

    Bon, J'ai compris ton erreur en tout cas avec FromHandle() : L'objet cr�� pour ce thread n'est pas un objet CTestDlg, mais un objet CWnd.
    Tu devrais essayer de cr�er un objet CTestDlg et appeler sa m�thode Attach() sur le HWND (quitte � appeler Detach() avant la fin du thread).
    ..
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parl� avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  5. #5
    Membre confirm�
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    150
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2006
    Messages : 150
    Par d�faut
    Oui mais je vais utiliser le syst�me des messages pour finir, ca � l'air bien plus simple, en faites je ne savais pas qu'on pouvait r�cup�rer la valeur de retour d'un SendMessage.

+ R�pondre � la discussion
Cette discussion est r�solue.

Discussions similaires

  1. [MFC] CFormView, Thread et rafraichissement
    Par Philippe299 dans le forum MFC
    R�ponses: 6
    Dernier message: 08/09/2005, 15h18
  2. [MFC] classe thread
    Par Joeleclems dans le forum MFC
    R�ponses: 13
    Dernier message: 24/05/2005, 14h31
  3. [MFC] multithread, communication p�re<->fils
    Par Joeleclems dans le forum MFC
    R�ponses: 19
    Dernier message: 19/05/2005, 10h31
  4. [MFC] dialog & thread & progressbar
    Par Tigris94 dans le forum MFC
    R�ponses: 4
    Dernier message: 05/04/2005, 15h51
  5. [MFC] UpdateData() + thread
    Par MadChris dans le forum MFC
    R�ponses: 6
    Dernier message: 03/06/2004, 20h55

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo