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

Langage C++ Discussion :

Pointeur dans un template


Sujet :

Langage C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Mai 2002
    Messages
    208
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2002
    Messages : 208
    Par défaut Pointeur dans un template
    Bonjour,

    J'ai le code suivant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    template<class CLASS>
    class A
    {
    	CLASS* owner;
    public:
    	A(CLASS* that)
    	{
    		owner = that;
    	};
    	~A(void){};
    };
    cela compile et je l'execute avec:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    class B
    {
    void Run(){ A<B> a(this); }
    };
    Le problème est que mon pointeur owner reste un pointeur sur rien après l'instruction owner = that;

    Quelqu'un aurait une idée du problème?

    Merci

  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
    Par défaut
    Salut,
    Va falloir un peu plus de code. Car dans le code que tu proposes, ce n'est pas le cas (en mode debug).

    P.S. CLASS comme nom d'un type paramétrique me semble une mauvaise idée : ça ressemble trop au mot clé class.

  3. #3
    Membre confirmé
    Profil pro
    Inscrit en
    Mai 2002
    Messages
    208
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2002
    Messages : 208
    Par défaut
    Mon problème n'a semble t'il rien à voir avec le template (le code du premier post fonctionne très bien)

    En fait j'essaie de faire un callback sur un membre d'instance en environnement multi thread. Et a priori c'est le multi thread qui pose problème.

    Voici le template du callback:
    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
     
    template<class CLASS, typename RET = void, typename ARG = void>
    class Callback
    {
    private:
    	typedef RET (CLASS::*Function)(ARG);
    	Function function;
    	CLASS* owner;
    public:
    	Callback(Function function, CLASS* that)
    	{
    		this->function = function;
    		this->owner = that;
    	};
     
    	~Callback(void){};
     
    	RET operator()(ARG a) { return call(a); };
     
    	RET call(ARG a) { return (owner->*function)(a); };
    };
     
     
    template<class CLASS, typename RET>
    class Callback<CLASS, RET, void>
    {
    private:
    	typedef RET (CLASS::*Function)();
    	Function function;
    	CLASS* owner;
    public:
    	Callback(Function function, CLASS* that)
    	{
    		this->function = function;
    		this->owner = that;
    	};
     
    	~Callback(void){};
     
    	RET operator()() { return call(); };
     
    	RET call() { return (owner->*function)(); };
    };
    L'instance de classe qui a la fonction à rappeler est multithread, ci dessous le code un peu simplifié.
    La fonction Request est statique
    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
     
    RemoteControlServer* RemoteControlServer::currentInstance = NULL;
    HANDLE RemoteControlServer::threadHandle = NULL;
     
    void  RemoteControlServer::Request()
    {
    	if(currentInstance == NULL)
    		currentInstance = new RemoteControlServer();
    	currentInstance->Start();
    }
     
    void RemoteControlServer::Run()
    {
    	RemoteControlComWrapper* remoteControlComWrapper = new RemoteControlComWrapper();
    	remoteControlComWrapper->DisplayApproval(&Callback<RemoteControlServer>(&RemoteControlServer::OnApprovalAccepted, this));
    }
    void RemoteControlServer::OnApprovalAccepted()
    {printf("Yeeeesss!!");}
     
    DWORD WINAPI  RemoteControlServer::ThreadStart(void* param)
    {
        RemoteControlServer* This = (RemoteControlServer*) param;
    	This->Run();
        return true;
    }
     
    void RemoteControlServer::Start()
    {
    	if(threadHandle != NULL) CloseHandle(threadHandle);
     
    	threadHandle = ::CreateThread(NULL, 0, RemoteControlServer::ThreadStart, (void*)this, 0, NULL);
    	if(threadHandle == NULL)
    	{
    		//
    	}
     
    	SetThreadPriority(threadHandle, THREAD_PRIORITY_LOWEST);
     
    	 WaitForSingleObject(threadHandle, INFINITE);
    }
    Notez que ce code fonctionne (le callback est bien appelé), pour le moment je n'arrive pas à reproduire le problème de mon projet dans un projet plus simple.

    Dans mon projet, la seule chose que j'ai trouvée est que l'égalité de pointeur dans la création de callback : this->owner = that; fonctionne si dans l'appel du constructeur, je remplace this par currentInstance.
    Mais le callback ne fonctionne pas pour autant

    Avez vous des pistes d'exploration à me donner?
    Qu'est ce qui peut empêcher de mettre un pointeur dans un autre?

  4. #4
    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
    Par défaut
    Salut,
    remoteControlComWrapper->DisplayApproval(&Callback<RemoteControlServer>(&RemoteControlServer::OnApprovalAccepted, this));Tu prends l'adresse d'un objet détruit dès la sortie de la fonction => comportement indéterminé ! Ce qui explique que ça peut avoir l'air de marcher en single thread mais pas en multithread.

    Deux remarques :
    1/ un wrapper comme Callback serait plutôt à manipuler par valeur et non par pointeur.

    2/ T'as entendu parler de tr1/std/boost::function et tr1/std/boost::bind ou tu es un fan du NIH

  5. #5
    Membre confirmé
    Profil pro
    Inscrit en
    Mai 2002
    Messages
    208
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2002
    Messages : 208
    Par défaut
    Tu prends l'adresse d'un objet détruit dès la sortie de la fonction
    Détruit aprsè quelle fonction?DisplayApproval ou le constructeur de Callback?

    Ce qui explique que ça peut avoir l'air de marcher en single thread mais pas en multithread.
    La création du callback et l'appel de la méthode callback est exécuter dans le même thread, le seul problème que je vois est que this est créé dans un thread et qu'il est passé en paramètre au callback dans un autre thread. Mais je vois pas ou est le problème


    1/ un wrapper comme Callback serait plutôt à manipuler par valeur et non par pointeur
    Je vais regardé ça....

    2/ T'as entendu parler de tr1/std/boost::function et tr1/std/boost::bind ou tu es un fan du NIH
    Ouais vaguement... je voulais juste faire quelque chose de simple et que je maitrise, mais c'est pas du tout le cas

  6. #6
    Membre confirmé
    Profil pro
    Inscrit en
    Mai 2002
    Messages
    208
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2002
    Messages : 208
    Par défaut
    Arfff! je comprends rien!!!
    J'ai supprimé toute notion de multithread dans mon test.
    Je crée le callback en dehors de la classe, cela fonctionne :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    A a;
    Callback<A> mycall(&A::OnApprovalAccepted, &a);
    a.Test(mycall);
    Je fais la même chose(ie création du callback), à l'intérieur de la classe A, cela ne fonctionne pas:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    void A::Run()
    {
    	Callback<A> mycall(&A::OnApprovalAccepted, this);
    	Test(mycall);
    }
    J'ai une erreur "Violation d'accès 0xbiduletrucmachinchose" à l'appel de la fonction du callback:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    return (owner->*function)();
    As tu une explication?

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Libération de pointeurs dans un std::vector
    Par G dans le forum SL & STL
    Réponses: 17
    Dernier message: 06/04/2005, 22h37
  2. Réponses: 2
    Dernier message: 15/11/2004, 15h12
  3. cast dans un template
    Par olivic dans le forum Langage
    Réponses: 15
    Dernier message: 20/10/2004, 14h10
  4. Utilisation de Pointeurs dans API windows
    Par Drooxy dans le forum API, COM et SDKs
    Réponses: 4
    Dernier message: 13/03/2003, 22h39
  5. [Turbo Pascal] Allocation et désallocation de pointeurs dans une fonction
    Par neird dans le forum Turbo Pascal
    Réponses: 13
    Dernier message: 17/11/2002, 20h14

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