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

C++ Discussion :

probleme avec Callback dans un objet utilisant une Dll


Sujet :

C++

  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Février 2003
    Messages
    837
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations forums :
    Inscription : Février 2003
    Messages : 837
    Points : 377
    Points
    377
    Par défaut probleme avec Callback dans un objet utilisant une Dll
    Bonjour à tous,

    Je suis actuellement en train d'ecrire un objet qui va me servir à utiliser une dll non managée dans du code managé. Voici en gros le principe au cas ou je m'exprime mal et que vous ne compreniez pas vraiment le but :

    Dll non managée avec des types C/C++ non utilisables en dotnet -> appel des fonctions non managées dans un objet C++ utilisant les deux sortes de types : managé et non managé -> appel à cet objet en code managé.

    Pour résumer, mon objet C++ va se charger de traduire les types non managés en types managés. Bref, je crois que je me repete là ^^


    Donc mon objet est de la sorte :


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    class objetBT
    {
    void RegisterCallBack()
    {
    BT_RegisterCallBack(EVENT_CONNECT, myCallBackConnect)
    }
     
    void myCallBackConnect()
    {
    //Je raise un event ici
    }
    }
    Ceci est le principe de ma classe, pas le code définitif !
    Donc dans registerCall back j'appelle BT_RegisterCallback qui est une fonction de la dll non managée, elle est comme ca et je ne peux pas la changer.
    Via cette fonction je lie l'evenement EVENT_CONNECT à la methode MyCallBackConnect comme ça lorsque la dll non managée lance un évenement, elle execute le code de ma fonction mycallbackconnect.
    Seul probleme : ce que j'ai indiqué comme maniere de faire est incorrect. Ca ne passe pas en C++. Par contre si je place void MyCallBackConnect hors de la classe, ça passe mais ce n'est pas mon but car je souhaite lancer un evenement quand j'execute la fonction MyCallBackConnect.

    Je voulais donc savoir si quelqu'un pouvait me filer un petit coup de main pour ça svp ? car je ne sais pas du tout comment faire.

    Petit PS : mon objet ne doit etre instancié qu'une seule fois (si ça peut aider, car je crois qu'il pourrait y avoir un rapport)

    Merci à tous

    @+

  2. #2
    r0d
    r0d est déconnecté
    Expert éminent

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    4 264
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Août 2004
    Messages : 4 264
    Points : 6 683
    Points
    6 683
    Billets dans le blog
    2
    Par défaut
    Bonjour,

    si tu veux absolument que ta callback soit dans ta classe, elle doit être déclarée statique (mot-clé 'static'). Cela implique que tu ne pourra modifier que les paramètres statiques de la classe.

    Le pattern utilisé habituellement pour les callback consiste à passer un paramètre "context" à la callback. Ce context est un pointeur vers l'objet qui doit être modifié par cette callback.

    Hope it helps.

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Février 2003
    Messages
    837
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations forums :
    Inscription : Février 2003
    Messages : 837
    Points : 377
    Points
    377
    Par défaut
    Salut,

    Merci pour ta réponse. Pour le static, j'ai essayé de declarer ma fonction en static mais il me dit qu'il ne peut pas tant qu'il n'a pas un acces à une instance.... malheureusement

    Donc là je galere vraiment.
    Pourrais tu me dire comment tu procederait à ma place pour faire ce que je cherche à faire sachant ceci :

    La fonction BT_RegisterCallback permet de lier un evenement de la dll non managée à une méthode/fonction.
    Moi, j'aimerai lier l'evenement de la dll non managée (dans ma méthode de classe) à une methode/fonction de ma classe.

    Voici la signature de BT_RegisterCallback :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    DWORD BT_RegisterCallback( 
    /* [in] */ UCHAR ucEvent, 
    /* [in] */ LPVOID pfnCbkFun 
    );
    Voici un exemple de signature que doit avoir la methode/fonction liée à l'evenement (car il y a plusieurs signatures selon l'evenement).

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    typedef void (*PCALLBACK_CONNECTION_STATE_CHANGED)  
    (WORD wServiceClass, BYTE* lpBdAddr, UCHAR ucStatus, DWROD 
    dwConnetionHandle);
    Donc grosso modo il faudrait que ma classe ressemble à cela :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    class objetBT
    	{
    	void RegisterCallBack()
    		{
    		BT_RegisterCallBack(EVENT_CONNECTION_STATUS, connection_state_changed)
    		}
     
    	void connection_state_changed(WORD wServiceClass, BYTE* lpBdAddr, UCHAR ucStatus, DWROD 
    dwConnetionHandle)
    		{
    		//Je raise un event managé ici
    		}
    	}
    Malheureusement, mes compétences m'abandonnent ici...
    Je suis degouté car c'est juste ce petit truc qui m'embete sinon le reste pourrait aller... Je suis vraiment frustré à cause de ça...

    Aurais tu une idée stp ?
    En plaçant static devant la methode connection_state_changed ca ne passe pas comme je t'explique au debut.

    Merci d'avance
    @ bientot

    ps : si tu as besoin d'infos supplementaires n'hesites pas

  4. #4
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Points : 15 920
    Points
    15 920
    Par défaut
    Il faut effectivement que ta callback soit une fonction membre statique, une fonction membre non-statique ayant un prototype et un comportement différent.
    Mais ce ne sera pas bien gênant, si tu n'as qu'une instance de objetBT tu peux l'utiliser pour appeler la fonction membre voulue.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    class objetBT
    {
        void RegisterCallBack()
        {
            BT_RegisterCallBack(EVENT_CONNECTION_STATUS,  &objetBT::connection_state_changed);
        }
     
        static void connection_state_changed(WORD wServiceClass, BYTE* lpBdAddr, UCHAR ucStatus, DWORD dwConnectionHandle)
        {
            monInstanceObjetBT->FaireQuelqueChose();
        }
    }

  5. #5
    Membre averti
    Profil pro
    Inscrit en
    Février 2003
    Messages
    837
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations forums :
    Inscription : Février 2003
    Messages : 837
    Points : 377
    Points
    377
    Par défaut
    Salut Laurent.

    Ca ne passe toujours pas avec cette methode

    Voici le code et le message d'erreur qui va avec :

    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
     
    public ref class Class1
    	{
    	public : 
    		Class1()
    		{
     
    		}
     
    		bool BTAPI_RegisterCallback()
    		{
    			DWORD dwResult;
    			dwResult = BT_RegisterCallback(EVENT_CONNECTION_STATUS, &Class1::CBK_Connection);
    			return true;
    		}
     
    		static void CBK_Connection(WORD wServiceClass, BYTE* lpBdAddr, UCHAR ucStatus, DWORD dwConnetionHandle)
    		{
    		}
    	};
    et le message d'erreur :
    Error 1 error C3374: can't take address of 'BlueSoleilAPI::Class1::CBK_Connection' unless creating delegate instance m:\bluesoleilapi\bluesoleilapi\BlueSoleilAPI.h 52
    Donc là toujours pareil, je suis un peu largué... enfin je comprend le problème mais je ne vois pas comment le résoudre.

    Merci d'avance
    @+

  6. #6
    Membre averti
    Profil pro
    Inscrit en
    Février 2003
    Messages
    837
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations forums :
    Inscription : Février 2003
    Messages : 837
    Points : 377
    Points
    377
    Par défaut
    Re !

    C'est good, j'ai réussi à compiler... Il fallait enlever le ref du public ref class et passer en static la methode en question.
    Par contre, je n'ai pas encore testé le bousin car je ne sais pas lever d'évenement managé en c++
    J'etais en train de lire un peu de doc sur la msdn mais je ne trouve pas d'exemple concret donc bon, je vais essayer de chercher un peu plus ce soir apres le taf...

    Merci !!!!

    ps : si quelqu'un a un exemple d'evenement tout pret je suis preneur

    @++

  7. #7
    Membre averti
    Profil pro
    Inscrit en
    Février 2003
    Messages
    837
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations forums :
    Inscription : Février 2003
    Messages : 837
    Points : 377
    Points
    377
    Par défaut
    Bon c'est encore moi...

    En fait le faire d'avoir retiré le mot clef ref me rend mes methodes invisibles à l'exterieur... Je m'en suis rendu compte en essayant d'utiliser la dll générée... Du coup je ne peux plus rien faire donc c'est un peu bidon...
    Je ne sais pas quoi faire
    Laurent, par rapport au code que j'ai envoyé à l'avant dernier message, que penses tu ?
    Mon problème est que ça a tellement changé entre le c++ et le c++ dot net que je me sens un peu vite largué... mais malheureusement, faut que je trouve cette satanée solution, j'ai pas le choix...
    Merci d'avance

    @bientot

    ps : pour les evenements je me suis trouvé de la doc, ca devrait le faire je pense

  8. #8
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 379
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 379
    Points : 41 573
    Points
    41 573
    Par défaut
    Je pense que tu devrais passer à ta DLL non-managée une callback située hors de toute classe managée, qui appellerait des delegates ou des interfaces managées.

  9. #9
    Membre averti
    Profil pro
    Inscrit en
    Février 2003
    Messages
    837
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations forums :
    Inscription : Février 2003
    Messages : 837
    Points : 377
    Points
    377
    Par défaut
    Salut,

    Ca pourrait etre une solution en effet. Mais faut que je creuse le sujet.
    Sinon j'ai repéré cet article (pour les personnes qui pourraient avoir le meme probleme que moi, ca peut leur servir).

    http://www.supinfo-projects.com/fr/2...per_dotnet_fr/

    C'est assez simple et bien ecrit sur les bases d'un wrapper (terme que je ne connaissais d'ailleurs pas ^^)
    Merci

    @++

Discussions similaires

  1. Probleme avec STRTR dans une CLI ubuntu
    Par boutmos dans le forum Langage
    Réponses: 8
    Dernier message: 14/10/2014, 07h34
  2. Probleme avec CTimer dans une vue d'une appli
    Par vdaanen dans le forum MFC
    Réponses: 16
    Dernier message: 24/08/2011, 11h19
  3. probleme avec property dans une class
    Par Dereck07 dans le forum Débuter
    Réponses: 3
    Dernier message: 03/01/2010, 23h07
  4. Probleme avec critere dans une requete sur access..
    Par emirov dans le forum Requêtes et SQL.
    Réponses: 1
    Dernier message: 05/04/2008, 23h11
  5. [linker]Probleme avec SDL dans une application Ogre3D
    Par smarties dans le forum Visual C++
    Réponses: 2
    Dernier message: 15/01/2007, 14h29

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