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++/CLI Discussion :

Passage objet managé à une callback appelée par une dll native


Sujet :

C++/CLI

  1. #1
    Membre à l'essai
    Inscrit en
    Juin 2010
    Messages
    21
    Détails du profil
    Informations forums :
    Inscription : Juin 2010
    Messages : 21
    Points : 15
    Points
    15
    Par défaut Passage objet managé à une callback appelée par une dll native
    Bonjour à tous,

    Pb assez spécifique d'où l'intitulé qui fait 20bornes

    Je développe un projet Windows Form en c++ managé qui nécessite l'utilisation d'une dll native.

    Celle-çi contient une méthode du type :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    void addCallback(void* object, void (*returnValueCallback)(void*, int));
    Voici l'interface de mon objet managé :

    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
     
    #pragma once
     
    #include "cli_ptr.h"
     
    using namespace System;
    using namespace System::Windows::Forms;
     
    public ref class MonObjet
    {
    public:
    	MonObjet(String^ name, String^ ip, int port);
    	~MonObjet();
     
    	String^ m_name;
    	String^ m_ip;
    	int m_port;
     
    };
    et l'implémentation :

    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
     
    #include "stdafx.h"
    #include "MonObjet.h"
     
    void callback_portMonObjetValueChanged(void* baton, int port);
     
    MonObjet::MonObjet(String^ name, String^ ip, int port)
    {
    	m_name = name;
    	m_ip = ip;
    	m_port = port;
     
    	shared_ptr<cli_ptr<MonObjet>> ptr = cli_ptr<MonObjet>::Create(this);
    	void* objetVoid = ptr->GetNative();
     
    	maDll->addCallback(objetVoid , &callback_portMonObjetValueChanged);
     
    }
     
    MonObjet::~MonObjet()
    {
     
    }
     
    ///////////////////////////////////////////////////////////
    //Callbacks
    ///////////////////////////////////////////////////////////
     
    void callback_portMonObjetValueChanged(void* objet, int port)
    {
    	// get the managed object
    	shared_ptr<cli_ptr<MonObjet>> ptr2 =  cli_ptr<MonObjet>::Create(objet);
    	MonObjet^ monObjet= ptr2->GetManaged<MonObjet>();
     
    	// update the MonObjet port attribute
    	monObjet->m_port = port;
    }
    Pour convertir mon O.M. en void* (qui sera en fait le premier arg du callback appelé par ma dll) et vice-versa j'utilise la merveilleuse classe "cli_ptr" que j'ai trouvé sur le blog de Paslatek http://www.paslatek.net/shared_ptr-o...090909-23.aspx

    Mon pb : impossible de récup la bonne instance de MonObjet dans le callback
    Je récupère bien un Objet du type MonObjet mais impossible d'accéder à ses membres, monObjet est nullptr !

    Je précise que la classe "cli_ptr" fonctionne si je l'utilise simplement, sans passer par la dll native.

    Ce que je veux faire est il possible ?
    Si oui j'ai du faire une bourde qlq part...
    Qlq'un a-t-il une idée svp ?

  2. #2
    Membre éclairé

    Homme Profil pro
    Inscrit en
    Octobre 2008
    Messages
    426
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Puy de Dôme (Auvergne)

    Informations forums :
    Inscription : Octobre 2008
    Messages : 426
    Points : 827
    Points
    827
    Par défaut
    Salut,

    Et ça, ça peut t'aider?? C'est dans la FAQ : Comment utiliser des objets managés dans une classe native ?


    Oups,
    Je me rends compte que je suis hors sujet, ici il s'agit de créer un nouvel objet, pas de le transformer...
    Toutes mes excuses...

  3. #3
    Membre à l'essai
    Inscrit en
    Juin 2010
    Messages
    21
    Détails du profil
    Informations forums :
    Inscription : Juin 2010
    Messages : 21
    Points : 15
    Points
    15
    Par défaut
    Salut bertry,

    Je me rends compte que je suis hors sujet, ici il s'agit de créer un nouvel objet, pas de le transformer...
    Oui effectivement ce n'est pas ce que je recherche, je veux juste convertir l'instance de mon objet managé en void* pour le passer à ma dll et la re-convertir en instance d'objet managé dans le callback appelé par ma dll pour effectuer un traitement dessus.

    Je récupère bien un void* non nul dans ce callback mais lorsque je veux faire la conversion inverse, l'objet que j'obtiens est à "valeur non définie" :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    // get the managed object
    	shared_ptr<cli_ptr<MonObjet>> ptr2 =  cli_ptr<MonObjet>::Create(objet);
    	MonObjet^ monObjet= ptr2->GetManaged<MonObjet>();
    Je me demande si je ne perds pas l'adresse de l'instance de mon objet due à la différence d'allocation entre du code managé et du code natif...

    Mais merci quand même pour ton post bertry !
    Ca ne peut que faire avancer le schmilblik

    Quelqu'un d'autre aurait une idée svp ?

  4. #4
    Membre à l'essai
    Inscrit en
    Juin 2010
    Messages
    21
    Détails du profil
    Informations forums :
    Inscription : Juin 2010
    Messages : 21
    Points : 15
    Points
    15
    Par défaut
    Bon j'ai trouvé une solution de contournement en parcourant la FAQ, merci encore nico-pyright !

    Je crée finalement une classe native "de ma classe managée" qui va faire le dialogue avec ma dll native, et plus de pb de passage de callbacks

    Je passe à ma classe native une instance de mon managé avec gcroot pour y avoir accès et le tour est joué !

    Pour ceux qui auront un pb similaire, voici le code du .h:

    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
     
    #pragma once
     
    using namespace System;
    using namespace System::Windows::Forms;
     
    class MonObjetNatif;
     
    public ref class MonObjet
    {
    public:
    	MonObjet(String^ name, String^ ip, int port);
    	~MonObjet();
     
    	String^ m_name;
    	String^ m_ip;
    	int m_port;
     
    };
     
    class MonObjetNatif
    {
    public:
             MonObjetNatif(MonObjet^ monObjet);
    	~MonObjetNatif();
     
             void setPort(int port)
            {
               m_objetManage->m_port = port;
            };
     
    private:
             gcroot<MonObjet^>  m_objetManage;
    }
    De cette façon je passe directement l'instance de mon objet natif au callback appelé par ma dll dans lequel j'appelle la méthode setPort(...).

  5. #5
    Expert éminent sénior
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    5 074
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Février 2005
    Messages : 5 074
    Points : 12 120
    Points
    12 120
    Par défaut
    La solution marche car vous utilisez une référence managé, le "^" de MonObjet^.

    Le problème n'est pas trop un problème de mapping, mais que les objets .NET change souvent de place en mémoire pour des problématiques de garbage collection.

    Donc évitez les void* sur des objets .NET.

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

Discussions similaires

  1. Réponses: 12
    Dernier message: 11/09/2012, 19h48
  2. Appel d'une classe Java par une page HTML
    Par kqman dans le forum Général Java
    Réponses: 7
    Dernier message: 06/04/2011, 14h58
  3. Variable dans une fonction appelée par une autre fonction
    Par CyrilD dans le forum Général JavaScript
    Réponses: 7
    Dernier message: 21/12/2010, 13h42
  4. Appel d'une fonction C++ par une DLL en C
    Par oodini dans le forum C++
    Réponses: 4
    Dernier message: 03/02/2009, 14h44
  5. Appel d'une séquence sonore par une fonction
    Par Henri dans le forum Code::Blocks
    Réponses: 1
    Dernier message: 05/11/2007, 01h55

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