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

Threads & Processus C++ Discussion :

Classe Abstraite et Thread ..


Sujet :

Threads & Processus C++

  1. #1
    Membre régulier
    Profil pro
    System Integration Project Manager
    Inscrit en
    Octobre 2006
    Messages
    219
    Détails du profil
    Informations personnelles :
    Âge : 50
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : System Integration Project Manager
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Octobre 2006
    Messages : 219
    Points : 112
    Points
    112
    Par défaut Classe Abstraite et Thread ..
    Bonjour

    je rencontre un pb que je n'arrive pas a elucider ...

    J'ai la hiearchie de classe suivante:

    Classes abstraites
    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
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
     
    class IComputerSuper
    {
    public:
        IComputerSuper() : m_pThread(0)
    	{	};
     
    	virtual ~IComputerSuper()
    	{	if (m_pThread) delete m_pThread;	};	// TODO : dois-je le faire ?
     
    	virtual UINT Proceed() =0
    	{	return false;};
     
    	virtual bool Start()
    	{
    		m_Status = ERR;
    		if (m_pWnd == NULL)	
    		{
    			LOGERR("Notification window no set");
    			return false;
    		}
     
    		m_pThread = AfxBeginThread(ThreadFunc,this);
    		if (m_pThread)	LOGERR("Thread creation failed");
    		return (m_pThread != NULL);
    	}
     
    protected:
    	static UINT ThreadFunc(LPVOID pParam)
    	{ 
    		IComputerSuper *l_pComp = reinterpret_cast<IComputerSuper *>(pParam);
    		if (l_pComp)
    		{
    			if (l_pComp->Proceed())
    				return 0;
    		}
    		return 1;
    	};
    };
     
    template <typename VALUE1, typename VALUE2>
    class IComputer : public IComputerSuper
    {
    	// rien que des méthodes et des données d'interface ici ...
    };
    et une classe concrete qui effectue un calcul un peu long ...

    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
     
    class CConcreteComputer : protected IComputer<BYTE,WORD>
    {
    	public :
    		CConcreteComputer() : IComputer()
    		{	};
     
    		virtual ~CConcreteComputer()
    		{	};
     
    		virtual bool Proceed()
    		{
    			// fait les calculs.....
    		};
    };
    Voici les pb que je rencontre :
    1) dans la classe concrete, la ligne qui lance le thread (AfxBeginThread) genere des erreurs de compil. D'apres le message et la msdn, il ne reconnait pas la signature de la fonction.
    L'erreur classique est que la fonction (ThreadFunc dans mon cas) n'est pas static our moi, elle l'est !
    Ppur contourner le pb, j'ai réécrit la ligne AfxBeginThread comme ceci
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
     AfxBeginThred((AFX_THREADPROC)(ThreadFunc),this);
    Ce qui passe a la compil mais ...

    2) mon thread n'est pas lancé ...

    J'ai fait un petit programme de test avec les memes considerations (classe abstraite) et ca marche correctement ...
    La seule différence est la présence dans le cas présenté ici qu'il y a une classe abstraite générique intermediaire ... Est-ce que ca peut venir de là ?
    Je doute ...

    Si quelqu'un a une idée ou voit une c....e évidente, merci de m'aider ...

    V

  2. #2
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Points : 13 017
    Points
    13 017
    Par défaut
    Salut,
    Ton code compile sans le cast chez moi. Eventuellement, tu peux préciser comme ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    m_pThread = AfxBeginThread(IComputerSuper::ThreadFunc,this)
    En revanche, certaines choses m'interroge :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    	virtual ~IComputerSuper()
    	{	if (m_pThread) delete m_pThread;	};	// TODO : dois-je le faire ?
    -> Il n'y a pas un autodelete ?
    -> Si tu gères la destruction du thread, tu devrais soit interdire la copie IComputerSuper soit encapsuler m_pThread dans une classe RAII
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    virtual UINT Proceed() =0
    La signature diffère dans CConcreteComputer :
    Il n'y aurait pas une erreur :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    if (m_pThread)	LOGERR("Thread creation failed");
    le test ne serait pas :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    if (0==m_pThread)	LOGERR("Thread creation failed");
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    virtual UINT Proceed() =0
    	{	return false;};
    ??? Pourquoi donner un corps à ta méthode virtuelle pure ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    virtual UINT Proceed() =0;

  3. #3
    Membre régulier
    Profil pro
    System Integration Project Manager
    Inscrit en
    Octobre 2006
    Messages
    219
    Détails du profil
    Informations personnelles :
    Âge : 50
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : System Integration Project Manager
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Octobre 2006
    Messages : 219
    Points : 112
    Points
    112
    Par défaut
    Hello,

    Citation Envoyé par 3DArchi Voir le message
    Salut,
    Ton code compile sans le cast chez moi. Eventuellement, tu peux préciser comme ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    m_pThread = AfxBeginThread(IComputerSuper::ThreadFunc,this)
    Ca compile pas non plus ....

    Citation Envoyé par 3DArchi Voir le message
    En revanche, certaines choses m'interroge :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    	virtual ~IComputerSuper()
    	{	if (m_pThread) delete m_pThread;	};	// TODO : dois-je le faire ?
    -> Il n'y a pas un autodelete ?
    -> Si tu gères la destruction du thread, tu devrais soit interdire la copie IComputerSuper soit encapsuler m_pThread dans une classe RAII
    je ne sais pas s'il y a un autodelete .. Je dois investiguer. Pour le RAII, je verrai selon ce que j'ai trouvé ...

    Citation Envoyé par 3DArchi Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    virtual UINT Proceed() =0
    La signature diffère dans CConcreteComputer :
    Il n'y aurait pas une erreur :
    Oui, erreur de copier/coller et de retranscription.
    En fait dans mon appli, c'est la version qui renvoie un bool que j'utilise
    Citation Envoyé par 3DArchi Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    if (m_pThread)	LOGERR("Thread creation failed");
    le test ne serait pas :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    if (0==m_pThread)	LOGERR("Thread creation failed");
    Encore une erreur de recopie manuelle

    Citation Envoyé par 3DArchi Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    virtual UINT Proceed() =0
    	{	return false;};
    ??? Pourquoi donner un corps à ta méthode virtuelle pure ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    virtual UINT Proceed() =0;
    il n'y a pas de raison precise ... J'ai ajouté la virtualité pure apres avoir defini le retour par defaut .. Cette classe n'est pas encore totalement finalisée ..

    V

  4. #4
    Membre actif Avatar de Grulim
    Profil pro
    Inscrit en
    Juillet 2004
    Messages
    234
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2004
    Messages : 234
    Points : 288
    Points
    288
    Par défaut
    Pourquoi utilises-tu AfxBeginThread ? tu travailles en MFC ?
    Peut-on voir le message d'erreur exact ?

  5. #5
    Membre régulier
    Profil pro
    System Integration Project Manager
    Inscrit en
    Octobre 2006
    Messages
    219
    Détails du profil
    Informations personnelles :
    Âge : 50
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : System Integration Project Manager
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Octobre 2006
    Messages : 219
    Points : 112
    Points
    112
    Par défaut
    Citation Envoyé par Grulim Voir le message
    Pourquoi utilises-tu AfxBeginThread ? tu travailles en MFC ?
    Peut-on voir le message d'erreur exact ?
    Oui, je bosse en MFC, sous VS 2005.

    Voici le message du compilo:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    d:\users\daanen\projets\2602 - prostate biopsy\version 2.0.0 d\tech comp\sources\uc_mrimagecomputer\mrimagecomputer.h(71) : error C2665: 'AfxBeginThread'ÿ: aucune des 2 surcharges n'a pu convertir tous les types d'arguments
            c:\program files\microsoft visual studio 8\vc\atlmfc\include\afxwin.h(4202): peut ˆtre 'CWinThread *AfxBeginThread(AFX_THREADPROC,LPVOID,int,UINT,DWORD,LPSECURITY_ATTRIBUTES)'
            c:\program files\microsoft visual studio 8\vc\atlmfc\include\afxwin.h(4205): ou 'CWinThread *AfxBeginThread(CRuntimeClass *,int,UINT,DWORD,LPSECURITY_ATTRIBUTES)'
            lors de la tentative de mise en correspondance de la liste des arguments '(overloaded-function, IMrImageComputerSuper *const )'
    Bon après une recompilation complète, ça rentre dans la méthode de calcul, c'est déjà un bon point (fonctionnel).

    Mais même en recompilant toute la solution, sans le cast, j'ai cette erreur C2665

    V

  6. #6
    Membre actif Avatar de Grulim
    Profil pro
    Inscrit en
    Juillet 2004
    Messages
    234
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2004
    Messages : 234
    Points : 288
    Points
    288
    Par défaut
    Je ne suis pas un spécialiste des MFC, mais je pense que ta fonction statique n'a pas la bonne convention d'appel.
    Je m'explique, d'après la doc MS:
    Parameters

    pfnThreadProc
    Points to the controlling function for the worker thread. Cannot be NULL. This function must be declared as follows:
    UINT __cdecl MyControllingFunction( LPVOID pParam )
    ta fonction statique doit utiliser, implicitement, une autre convention d'appel (comme __thiscall), mais tu dois pouvoir la préciser explicitement dans la définition de fonction.
    Ou alors... As-tu essayer de caster le this en LPVOID ?

    Un dernier avis pendant que j'y suis : plutôt que statique, je définirais la fonction comme étant "amie", mais c'est plus une question de gout qu'autre chose...

  7. #7
    Membre régulier
    Profil pro
    System Integration Project Manager
    Inscrit en
    Octobre 2006
    Messages
    219
    Détails du profil
    Informations personnelles :
    Âge : 50
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : System Integration Project Manager
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Octobre 2006
    Messages : 219
    Points : 112
    Points
    112
    Par défaut
    Citation Envoyé par Grulim Voir le message
    Je ne suis pas un spécialiste des MFC, mais je pense que ta fonction statique n'a pas la bonne convention d'appel.
    Je m'explique, d'après la doc MS:


    ta fonction statique doit utiliser, implicitement, une autre convention d'appel (comme __thiscall),
    comme la fonction est statique, elle n'a pas de pointeur this et a donc la convention __cdecl

    Citation Envoyé par Grulim Voir le message
    mais tu dois pouvoir la préciser explicitement dans la définition de fonction.
    J'ai essayé de préciser __cdecl (avant de poster sur le forum) mais ca n'a rien changé ...

    Citation Envoyé par Grulim Voir le message
    Un dernier avis pendant que j'y suis : plutôt que statique, je définirais la fonction comme étant "amie", mais c'est plus une question de gout qu'autre chose...
    Je ne vois pas ce que ca changera ... Si la methode est friend, elle appartiendra a une classe et relevera donc de la convention __thiscall a moins de la déclarer.... en static donc ca se mord la queue ...

    V

  8. #8
    Membre actif Avatar de Grulim
    Profil pro
    Inscrit en
    Juillet 2004
    Messages
    234
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2004
    Messages : 234
    Points : 288
    Points
    288
    Par défaut
    Citation Envoyé par vdaanen Voir le message
    comme la fonction est statique, elle n'a pas de pointeur this et a donc la convention __cdecl



    J'ai essayé de préciser __cdecl (avant de poster sur le forum) mais ca n'a rien changé ...
    V
    Ca provenait de mon expérience avec CreateThread, qui nécessite non seulement static mais aussi __stdcall.

    Citation Envoyé par vdaanen Voir le message
    Je ne vois pas ce que ca changera ... Si la methode est friend, elle appartiendra a une classe et relevera donc de la convention __thiscall a moins de la déclarer.... en static donc ca se mord la queue ...

    V
    Soit j'ai oublié mon C++, soit tu fais erreur... une fonction amie n'est pas une fonction membre d'une classe, elle n'a pas de pointeur this...

  9. #9
    Membre régulier
    Profil pro
    System Integration Project Manager
    Inscrit en
    Octobre 2006
    Messages
    219
    Détails du profil
    Informations personnelles :
    Âge : 50
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : System Integration Project Manager
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Octobre 2006
    Messages : 219
    Points : 112
    Points
    112
    Par défaut
    Citation Envoyé par Grulim Voir le message
    Ca provenait de mon expérience avec CreateThread, qui nécessite non seulement static mais aussi __stdcall..
    J'ai pas essayé __stdcall ... Vais voir ce que ca donne

    Citation Envoyé par Grulim Voir le message
    Soit j'ai oublié mon C++, soit tu fais erreur... une fonction amie n'est pas une fonction membre d'une classe, elle n'a pas de pointeur this...
    Oups .. j'ai lu trop vite ... Effectivement, une fonction friend n'a pas de pointeur this ..

    V

Discussions similaires

  1. [Debutant] Une classe abstraite en parametre ?
    Par kiroukou dans le forum Débuter
    Réponses: 8
    Dernier message: 03/02/2005, 15h05
  2. [Débutant(e)] toString + classes abstraites
    Par debdev dans le forum Langage
    Réponses: 9
    Dernier message: 26/01/2005, 15h22
  3. [Debutant][Conception] Classes abstraites et interface.
    Par SirDarken dans le forum Langage
    Réponses: 4
    Dernier message: 29/10/2004, 00h02
  4. Classe abstraite / MVC
    Par caramel dans le forum MVC
    Réponses: 5
    Dernier message: 01/04/2003, 09h27
  5. pb constructeurs classes dérivant classe abstraite
    Par Cornell dans le forum Langage
    Réponses: 2
    Dernier message: 10/02/2003, 19h02

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