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 :

[Débutant C#] Passage d'un pointeur de méthode en paramètre vers une DLL


Sujet :

C#

  1. #1
    ILP
    ILP est déconnecté
    Membre confirmé
    Avatar de ILP
    Homme Profil pro
    Analyste programmeur
    Inscrit en
    Mai 2002
    Messages
    258
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Finistère (Bretagne)

    Informations professionnelles :
    Activité : Analyste programmeur
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2002
    Messages : 258
    Points : 610
    Points
    610
    Par défaut [Débutant C#] Passage d'un pointeur de méthode en paramètre vers une DLL
    Bonjour,
    Voilà mon problème : j'ai une DLL écrite en C++ que j'essaye d'appeller en C#.
    J'ai donc créé une classe contenant les méthodes exportés de la dll :
    Code C# : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    using System.Runtime.InteropServices;
     
    namespace MaDLL
    {
      public class maDLL
      {
        /// <summary>
        /// Changement du titre de la fenêtre.
        /// </summary>
        [DllImport("MaDLL.dll")]
        public static extern bool WndSetTitle(IntPtr hWnd,
          [MarshalAs(UnmanagedType.LPStr)] string pTitle);
      }
    }
    Le problème, c'est que cette DLL doit appeller une méthode du programme principal. Il y a donc une méthode recevant en paramètre un pointer vers cette méthode.
    Le code de la classe devrait ressembler à ça :
    Code C# : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    using System.Runtime.InteropServices;
     
    namespace MaDLL
    {
      public class maDLL
      {
        /// <summary>
        /// Envoi du pointer vers la méthode à exécuter par la DLL.
        /// </summary>
        [DllImport("MaDLL.dll")]
        public static extern bool SetProcHandler(IntPtr pfMyProc);
      }
    }
    Mais je sais pas comment appeller cette méthode en lui passant en paramètre un pointer vers une autre méthode .

    Pour info, le code d'appel de la fonction ressemble à ça en Pascal :
    Code Pascal : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    // Déclaration de la fonction exportée de la DLL
    function SetProcHandler(pfMyProc: Pointer): Boolean; stdcall; 
      external 'MaDLL.dll';
     
    // Déclaration de la fonction à exécuter par la DLL
    function MyProc(Prm1, Prm2: Integer): Integer;
    begin
      // ...
    end;
     
    // Envoi du pointer vers la fonction à exécuter
    SetProcHandler(@MyProc);
    Voilà, j'espère ne pas être trop confus dans ma demande .
    Merci d'avance pour vos réponse.

  2. #2
    Membre expérimenté Avatar de ctxnop
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juillet 2007
    Messages
    858
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Morbihan (Bretagne)

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

    Informations forums :
    Inscription : Juillet 2007
    Messages : 858
    Points : 1 732
    Points
    1 732
    Par défaut
    Salut,
    Je ne m'y connais pas beaucoup en P/Invoke, mais je vois bien un petit coup de reflection pour obtenir ton pointeur de fonction.
    Je ne suis pas en mesure de tester ma solution donc je te laisse ce boulot, ca donnerai quelque chose comme ca :
    Code C# : 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
     
    static class CoteDotNet
    {
    	// Cette méthode est celle appellée par ta DLL
    	// Le prototype doit donc correspondre.
    	// Il est probable que ca manque de quelques attributs d'interop, je ne connais pas assez les p/invoke.
    	public static int MethodeQuiSeraAppelle(int a, int b)
    	{
    		// Le code de la méthode
    	}
     
    	public static IntPtr GetPointeur()
    	{
    		// Cette ligne est a adapter pour récupérer la bonne méthode, selon si tu en a plusieur ou non
    		System.Reflection.MethodInfo mi = typeof(CoteDotNet).GetMethod("MethodeQuiSeraAppelle", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public);
    		return mi.MethodHandle.Value;
    	}
     
    	// Exemple d'utilisation
    	public static void BindProcHandler()
    	{
    		MaDLL.SetProcHandler(CoteDotNet.GetPointeur());
    	}
    }

  3. #3
    ILP
    ILP est déconnecté
    Membre confirmé
    Avatar de ILP
    Homme Profil pro
    Analyste programmeur
    Inscrit en
    Mai 2002
    Messages
    258
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Finistère (Bretagne)

    Informations professionnelles :
    Activité : Analyste programmeur
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2002
    Messages : 258
    Points : 610
    Points
    610
    Par défaut J'ai trouvé la solution !
    Désolé pour ton code ctxnop, mais je n'ai pas réussi à le faire fonctionner .
    Par-contre, j'ai finalement réussi à envoyer un pointeur vers ma DLL .

    Mon code donne quelque chose comme ça :

    Dans l'API utilisée pour appeller la DLL :
    Code C# : 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
    using System.Runtime.InteropServices;
     
    namespace MaDLL
    {
      public class maDLL
      {
        /// <summary>
        /// Envoi du pointer vers la méthode à exécuter par la DLL.
        /// </summary>
        [DllImport("MaDLL.dll")]
        public static extern bool SetProcHandler([MarshalAs(UnmanagedType.FunctionPtr)] MyProc pfMyProc);
     
        /// <summary>
        /// Méthode utilisée pour les messages de la DLL
        /// </summary>
        [UnmanagedFunctionPointer(CallingConvention.StdCall)]
        public delegate int SendProc(int Prm1, int Prm2);
      }
    }
    Dans le programme principal :
    Code C# : 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
    using MaDLL
     
    namespace MonProgramme
    {
      public partial class Principale : Form
      {
        /// <summary>
        /// Méthode à envoyer à la DLL
        /// </summary>
        static MaDLL.SendProc myProc = null;
     
        public Principale()
        {
          InitializeComponent();
     
          // Attribution de la procédure à utiliser
          myProc = new MaDLL.SendProc(MyProc);
     
          // Envoye la procédure à la DLL
          MaDLL.SetProcHandler(myProc);
     
          // Empêche la vidange du pointeur
          GC.KeepAlive(myProc);
        }
     
        public unsafe int MyProc(int Prm1, int Prm2)
        {
          return 0;
          // …
        }    
      }
    }
    Je vais quand même un peu tester pour voir s'il ça ne génère pas des erreurs.
    J'espère que ça pourra toujours être utile à quelqu'un .

  4. #4
    Membre expérimenté Avatar de ctxnop
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juillet 2007
    Messages
    858
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Morbihan (Bretagne)

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

    Informations forums :
    Inscription : Juillet 2007
    Messages : 858
    Points : 1 732
    Points
    1 732
    Par défaut
    Faut pas être désolé, comme j'avais dis je n'avais rien pour tester ma proposition, ca ne m'étonne donc pas qu'elle n'ait pas fonctionné. L'important est que tu as solutionné ton problème.

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

Discussions similaires

  1. Réponses: 2
    Dernier message: 02/09/2008, 11h37
  2. appeler une méthode avec paramètre dans une page JSP
    Par javasmif dans le forum Struts 2
    Réponses: 1
    Dernier message: 06/12/2007, 10h48
  3. Réponses: 8
    Dernier message: 05/07/2007, 13h44
  4. Réponses: 7
    Dernier message: 06/05/2006, 15h06
  5. Réponses: 4
    Dernier message: 01/12/2005, 12h33

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