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 d'une fonction d'une classe managee dans une dll c++ ou C (?) par delegate


Sujet :

C++/CLI

  1. #1
    Futur Membre du Club
    Homme Profil pro
    Inscrit en
    Juillet 2012
    Messages
    13
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Morbihan (Bretagne)

    Informations forums :
    Inscription : Juillet 2012
    Messages : 13
    Points : 8
    Points
    8
    Par défaut passage d'une fonction d'une classe managee dans une dll c++ ou C (?) par delegate
    Bonjour a tous, j'ai un petit pb de passage du monde non manage dans le monde manage..

    je possede une dll ecrite en je ne sais quoi (C++ je pense) dont une des methode est

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    typedef void(* cm2::fem::solver_static_Newton::operating_mode_type::display_handler_type)(unsigned level, const char *msg)
    le but étant de passer la fonction de gestion "log" en tant que parametre.

    pour le moment j'utilise une fonction globale, exterieure a une classe, qui est :

    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
    /**
            \fn        logfile_handler()
            \brief   utilise en tant que Handler pour les solveurs
     */	
    static void logfile_handler(unsigned level, const char* msg)
    {
       StreamWriter ^stream = File::AppendText("LOG.txt");
     
       if (level < 10) 
       {
          String ^message = gcnew String(msg);
          stream->WriteLine(message);
       }
     
       stream->Close();
    }
    et elle est passee en pointeur dans la classe de la dll par :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
       solver_static_Newton::operating_mode_type solver_operatingmode;
       // initialise le mode operatoire du solveur
     
       solver_operatingmode.display_hdl = &logfile_handler;


    Or, je voudrai utiliser des evenements .NET et de ce fait utiliser une
    methode interne a une classe managee.

    j'ai un peu regarde les fonctions de mashalisations et de delegate.

    j'ai une classe managee :

    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
    public ref class gsd_fea
      {
    constructeurs destructeur methodes etc...
     
    // je cree un delegate et une fonction qui me permettrait de gérer
            // le handler du solveur :
     
          public: delegate void gsdfea_delegate_logfile_handler(unsigned level, const char* msg);
     
          void gsdfea_logfile_handler(unsigned level, const char* msg)
          {
             StreamWriter ^stream = File::AppendText("LOGDELEGATE.TXT");
     
             if (level < 10)
             {
                String ^message = gcnew String(msg);
                stream->WriteLine(message);
             }
     
     
      }
             stream->Close();
          }
    }
    et la j'utilise la fonction de marshalisation pour passer du monde manage au non manage par :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
       solver_static_Newton::operating_mode_type solver_operatingmode;
     
       // initialise le mode operatoire du solveur
       gsd_fea::gsdfea_delegate_logfile_handler ^logtodo = gcnew gsd_fea::gsdfea_delegate_logfile_handler(this,&gsd_fea::gsdfea_logfile_handler);
       solver_operatingmode.display_hdl = (cm2::fem::solver_static_Newton::operating_mode_type::display_handler_type) Marshal::GetFunctionPointerForDelegate(logtodo).ToPointer();

    Le code compile sans warnings mais plante a l'execution comme si il n'arrivait pas a passer de messages ou d'arguments.

    Existe t'il une autre voie pour faire cela ?

  2. #2
    Futur Membre du Club
    Homme Profil pro
    Inscrit en
    Juillet 2012
    Messages
    13
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Morbihan (Bretagne)

    Informations forums :
    Inscription : Juillet 2012
    Messages : 13
    Points : 8
    Points
    8
    Par défaut
    peut etre ne suis je pas sur le bon forum..
    c'est plus du .NET que du C++/CLI ?

  3. #3
    Expert éminent sénior
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    5 072
    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 072
    Points : 12 118
    Points
    12 118
    Par défaut
    J'ai appris des trucs, merci.

    Primo, nommage C++ exporté d'une Dll, c'est bien pourri, l'éditeur de la Dll doit être un amateur.
    Je crains donc des "plaisanteries" avec des conventions d'appels "exotique" qui vont vous mettre dans l'embarras.

    http://msdn.microsoft.com/en-us/libr...v=vs.110).aspx
    Vous avez des petits détails comme l'utilisation de GCHandle::Alloc.

  4. #4
    Futur Membre du Club
    Homme Profil pro
    Inscrit en
    Juillet 2012
    Messages
    13
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Morbihan (Bretagne)

    Informations forums :
    Inscription : Juillet 2012
    Messages : 13
    Points : 8
    Points
    8
    Par défaut
    bonjour Bacelar,

    ravi que cela puisse servir a qque chose

    Qu'appelez vous "nommage" ?
    dans le code plus haut, a quoi est ce que ca se refere ?

    je peux echanger avec l'editeur de la dll pour que sa dll soit plus compatible, mais faut t'il encore que je sache quoi lui demander ;-)

    merci pour le doc, je vais lire ca avec attention deja

  5. #5
    Expert éminent sénior
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    5 072
    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 072
    Points : 12 118
    Points
    12 118
    Par défaut
    cm2: : fem : :solver_static_Newton::operating_mode_type::display_handler_type

    Ca ressemble à un nom C++ et non C.
    Mais l'éditeur à peut-être fourni des en-têtes compatible C++ pour encapsuler des fonctions C++.

    Utiliser dependency walker (http://www.dependencywalker.com/) sur la Dll pour vérifier que c'est bien des fonctions C qui sont exportées.

    Si c'est des fonctions C++ (avec une décoration des noms tout bizarre), c'est très très moyen car cela interdit d'utiliser un autre compilateur ou version des librairies que ceux utilisé pour générer le Dll.

    Bonne lecture.

  6. #6
    Expert éminent sénior
    Avatar de Mat.M
    Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2006
    Messages
    8 361
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2006
    Messages : 8 361
    Points : 20 379
    Points
    20 379
    Par défaut
    Salut juste une question
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    static void logfile_handler(unsigned level, const char* msg)
    ce qui me chagrine c'est de passer un char* , est-ce que c'est possible en code managed ?

  7. #7
    Expert éminent sénior
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    5 072
    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 072
    Points : 12 118
    Points
    12 118
    Par défaut
    C'est la Dll qui appelle, donc c'est elle qui mène le jeu. Il faut vous y conformer.
    Mais je ne vois pas de difficultés.
    Au début de votre fonction, vous n'avez qu'a créer une String^ avec la chaine passée en paramètre.

  8. #8
    Futur Membre du Club
    Homme Profil pro
    Inscrit en
    Juillet 2012
    Messages
    13
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Morbihan (Bretagne)

    Informations forums :
    Inscription : Juillet 2012
    Messages : 13
    Points : 8
    Points
    8
    Par défaut
    Paul,
    Ci joint la sortie. En cochant la case C++.

    je pense que effectivement la dll est propre a un compilateur car
    l'editeur fournit plusieurs versions. Notamment pour VS2008, VS2010 x86 et x64 etc.. Donc a moi de savoir quelle bibli utiliser.

    Pour les en tetes, c'est qque chose comme :
    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
     
    /**
       Abstract base class of all solver classes.
       */
    class CM2FEM_API solver_base : public fem::base_class 
    {
    public:
     
    ///
    typedef solver_base              self_type;
    ///
    typedef fem::base_class          parent_type;
     
    };
     
     
     
    /**
       Solver static linear.
       */
    class CM2FEM_API solver_static_linear : public solver_base 
    {
    public:
     
    etc...
    et je retrouve bien la syntaxe :

    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
     
     
       /**
          Operating mode type of the solver.
     
          This structure gathers flags and parameters to control the way the solver works.
          */
       struct CM2FEM_API operating_mode_type
       {
     
       /**
          Typedef for the display handler.
     
          \param   level    Level of message: 
                               -  0 = Basic message.
                               -  1 = Somewhat detailed message.
                               -  2 = Very detailed message (DEBUG mode only).
          \param   msg      Message.
          */
       typedef void (*display_handler_type) (unsigned level, const char* msg);
    je lui ai pose la question mais il ne connaissent pas du tout le CLI et notamment le .NET. Donc marshalling, interop etc... no ideas...
    Images attachées Images attachées  

  9. #9
    Expert éminent sénior
    Avatar de Mat.M
    Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2006
    Messages
    8 361
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2006
    Messages : 8 361
    Points : 20 379
    Points
    20 379
    Par défaut
    Citation Envoyé par denisdg Voir le message
    Le code compile sans warnings mais plante a l'execution comme si il n'arrivait pas a passer de messages ou d'arguments.
    ce n'est pas possible de mettre un point d'arrêt et tracer pas-à-pas ?

  10. #10
    Futur Membre du Club
    Homme Profil pro
    Inscrit en
    Juillet 2012
    Messages
    13
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Morbihan (Bretagne)

    Informations forums :
    Inscription : Juillet 2012
    Messages : 13
    Points : 8
    Points
    8
    Par défaut
    malheureusement non car dans la gestion du solveur,

    le mode de travail (et le handler) sont passé dans une classe operating_mode
    et le solveur appele par sa fonction run() doit utiliser qque part les parametres
    de cette classe.

    mais aucun n'est accessible donc.. rapé !

  11. #11
    Expert éminent sénior
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    5 072
    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 072
    Points : 12 118
    Points
    12 118
    Par défaut
    Je ne vois pas d'impossibilité.

    Vous passez un pointeur sur une fonction ok ?
    Qu'est-ce qui vous interdit de mettre un point d'arrêt au début de la dite fonction ?

  12. #12
    Futur Membre du Club
    Homme Profil pro
    Inscrit en
    Juillet 2012
    Messages
    13
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Morbihan (Bretagne)

    Informations forums :
    Inscription : Juillet 2012
    Messages : 13
    Points : 8
    Points
    8
    Par défaut
    exact ! pfff.. c'etait si evident.

    alors..
    j'ai modifié le code en ajoutant le GCHandle::Alloc(ledelegate);

    lors de la premiere iteration, le handler rentre bien dans la fonction
    avec les bons parametres et peut faire une premiere ecriture.

    ensuite, des le moment ou le programme sort de la fonction et doit retourner dans la suite du solveur pour commencer sa seconde iteration.. Exception !

    "
    An unhandled exception of type 'System.AccessViolationException' occurred in Ophelia.exe

    Additional information: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
    "

    j'ai regardé la doc la dessus :

    http://msdn.microsoft.com/fr-fr/libr...exception.aspx

    aie !!

  13. #13
    Expert éminent sénior
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    5 072
    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 072
    Points : 12 118
    Points
    12 118
    Par défaut
    Si vous ne lui avez pas fourni de pointeurs foireux ou de pointeurs sur objets managés "migrants", c'est que c'est chez lui qu'il y a un problème.

    Pouvez-vous avoir accès au code de la Dll, ou sinon à ses symboles shrinkés (.sym, .pdb, .deb, ...).

    L'éditeur a eu l'intelligence de ne pas intercepté en aveugle les exceptions, vous devriez donc avoir accès aux motifs réels du problème. Un pointeur foireux, fait juste savoir d'où il sort.

    Courage

  14. #14
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    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 369
    Points : 41 519
    Points
    41 519
    Par défaut
    Déjà, pourriez-vous poster votre code actuel? Dans une balise [ code ] si possible?
    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.

  15. #15
    Futur Membre du Club
    Homme Profil pro
    Inscrit en
    Juillet 2012
    Messages
    13
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Morbihan (Bretagne)

    Informations forums :
    Inscription : Juillet 2012
    Messages : 13
    Points : 8
    Points
    8
    Par défaut
    Bonsoir Paul,

    Assez d'accord sur le fait que cela semble chez lui qu'il y a un pb. je leur en ai fait part mais il ne connait pas le code managé (C++ pur). Malheureusemeent je n'ai pas acces au code. Cependant il sont a l'ecoute et je vais leur faire un petit exemple pour qu'il puissent debugger leur fonctions. Ca va avancer ;-)

    je mets la discussion comme "resolue" meme si ce n'est pas entierement vrai mais ppalement parceque je pense que mes methodes de delegate fonctionnent et que le pb est ailleurs.

    Médinoc,
    effectivement, je ferai attention dorénavant. J'ai decouvert tard la balise code mais c'est pas mal et je vais m'en servir.

    @bientot
    denis

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

Discussions similaires

  1. Plusieurs classes CSS dans une fonction JavaScript
    Par Lillie CHARLOTTE dans le forum Général JavaScript
    Réponses: 14
    Dernier message: 25/05/2015, 15h29
  2. Réponses: 1
    Dernier message: 07/10/2011, 10h21
  3. [Java] cast de classe Java dans une fonction Matlab
    Par steph_ch dans le forum MATLAB
    Réponses: 1
    Dernier message: 14/04/2008, 15h55
  4. Réponses: 5
    Dernier message: 09/03/2007, 21h14
  5. Réponses: 9
    Dernier message: 13/03/2006, 17h45

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