Précédent   Forum du club des développeurs et IT Pro > C et C++ > Outils pour C & C++ > Visual C++ > C++/CLI
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse
 
Outils de la discussion
Publicité
'
Vieux 10/10/2012, 00h13   #1
denisdg
Invité régulier
 
Homme Denis
Inscription : juillet 2012
Messages : 13
Détails du profil
Informations personnelles :
Nom : Homme Denis
Localisation : France, Morbihan (Bretagne)

Informations forums :
Inscription : juillet 2012
Messages : 13
Points : 5
Points : 5
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 :
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 :
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 :
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 :
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 :
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 ?
denisdg est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 10/10/2012, 11h01   #2
denisdg
Invité régulier
 
Homme Denis
Inscription : juillet 2012
Messages : 13
Détails du profil
Informations personnelles :
Nom : Homme Denis
Localisation : France, Morbihan (Bretagne)

Informations forums :
Inscription : juillet 2012
Messages : 13
Points : 5
Points : 5
peut etre ne suis je pas sur le bon forum..
c'est plus du .NET que du C++/CLI ?
denisdg est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 10/10/2012, 11h03   #3
bacelar
Expert Confirmé Sénior
 
Homme Paul Bacelar
Développeur informatique
Inscription : février 2005
Messages : 2 651
Détails du profil
Informations personnelles :
Nom : Homme Paul Bacelar
Âge : 41
Localisation : France

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

Informations forums :
Inscription : février 2005
Messages : 2 651
Points : 4 044
Points : 4 044
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.
bacelar est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 10/10/2012, 12h23   #4
denisdg
Invité régulier
 
Homme Denis
Inscription : juillet 2012
Messages : 13
Détails du profil
Informations personnelles :
Nom : Homme Denis
Localisation : France, Morbihan (Bretagne)

Informations forums :
Inscription : juillet 2012
Messages : 13
Points : 5
Points : 5
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
denisdg est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 10/10/2012, 12h50   #5
bacelar
Expert Confirmé Sénior
 
Homme Paul Bacelar
Développeur informatique
Inscription : février 2005
Messages : 2 651
Détails du profil
Informations personnelles :
Nom : Homme Paul Bacelar
Âge : 41
Localisation : France

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

Informations forums :
Inscription : février 2005
Messages : 2 651
Points : 4 044
Points : 4 044
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.
bacelar est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 10/10/2012, 14h43   #6
Mat.M
Expert Confirmé Sénior
 
Développeur informatique
Inscription : novembre 2006
Messages : 4 448
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 : 4 448
Points : 5 863
Points : 5 863
Salut juste une question
Code :
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 ?
Mat.M est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 10/10/2012, 15h17   #7
bacelar
Expert Confirmé Sénior
 
Homme Paul Bacelar
Développeur informatique
Inscription : février 2005
Messages : 2 651
Détails du profil
Informations personnelles :
Nom : Homme Paul Bacelar
Âge : 41
Localisation : France

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

Informations forums :
Inscription : février 2005
Messages : 2 651
Points : 4 044
Points : 4 044
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.
bacelar est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 10/10/2012, 20h49   #8
denisdg
Invité régulier
 
Homme Denis
Inscription : juillet 2012
Messages : 13
Détails du profil
Informations personnelles :
Nom : Homme Denis
Localisation : France, Morbihan (Bretagne)

Informations forums :
Inscription : juillet 2012
Messages : 13
Points : 5
Points : 5
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 :
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 :
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
Type de fichier : jpg Screenshot (20h 41m 09s).jpg (936,8 Ko, 6 affichages)
denisdg est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 11/10/2012, 10h39   #9
Mat.M
Expert Confirmé Sénior
 
Développeur informatique
Inscription : novembre 2006
Messages : 4 448
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 : 4 448
Points : 5 863
Points : 5 863
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 ?
Mat.M est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 11/10/2012, 16h44   #10
denisdg
Invité régulier
 
Homme Denis
Inscription : juillet 2012
Messages : 13
Détails du profil
Informations personnelles :
Nom : Homme Denis
Localisation : France, Morbihan (Bretagne)

Informations forums :
Inscription : juillet 2012
Messages : 13
Points : 5
Points : 5
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é !
denisdg est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 11/10/2012, 17h14   #11
bacelar
Expert Confirmé Sénior
 
Homme Paul Bacelar
Développeur informatique
Inscription : février 2005
Messages : 2 651
Détails du profil
Informations personnelles :
Nom : Homme Paul Bacelar
Âge : 41
Localisation : France

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

Informations forums :
Inscription : février 2005
Messages : 2 651
Points : 4 044
Points : 4 044
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 ?
bacelar est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 12/10/2012, 19h21   #12
denisdg
Invité régulier
 
Homme Denis
Inscription : juillet 2012
Messages : 13
Détails du profil
Informations personnelles :
Nom : Homme Denis
Localisation : France, Morbihan (Bretagne)

Informations forums :
Inscription : juillet 2012
Messages : 13
Points : 5
Points : 5
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 !!
denisdg est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 15/10/2012, 14h17   #13
bacelar
Expert Confirmé Sénior
 
Homme Paul Bacelar
Développeur informatique
Inscription : février 2005
Messages : 2 651
Détails du profil
Informations personnelles :
Nom : Homme Paul Bacelar
Âge : 41
Localisation : France

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

Informations forums :
Inscription : février 2005
Messages : 2 651
Points : 4 044
Points : 4 044
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
bacelar est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 15/10/2012, 14h23   #14
Médinoc
Expert Confirmé Sénior
 
Avatar de Médinoc
 
Homme
Développeur informatique
Inscription : septembre 2005
Messages : 22 396
Détails du profil
Informations personnelles :
Sexe : Homme
Âge : 29
Localisation : France

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

Informations forums :
Inscription : septembre 2005
Messages : 22 396
Points : 32 049
Points : 32 049
Envoyer un message via MSN à Médinoc
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.
Médinoc est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 27/10/2012, 01h54   #15
denisdg
Invité régulier
 
Homme Denis
Inscription : juillet 2012
Messages : 13
Détails du profil
Informations personnelles :
Nom : Homme Denis
Localisation : France, Morbihan (Bretagne)

Informations forums :
Inscription : juillet 2012
Messages : 13
Points : 5
Points : 5
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
denisdg est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Cette discussion est résolue.
Outils de la discussion

Navigation rapide


Fuseau horaire GMT +2. Il est actuellement 21h28.


 
 
 
 
Partenaires

Hébergement Web