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 :

Native C++ Callbacks in C# Code


Sujet :

C++/CLI

  1. #1
    Futur Membre du Club
    Profil pro
    Inscrit en
    D�cembre 2009
    Messages
    4
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : D�cembre 2009
    Messages : 4
    Par d�faut Native C++ Callbacks in C# Code
    Bonjour � tous,

    Dans un programme C# j'appelle une dll C++ native dans laquelle j'installe un hook qui leve un callback que je souhaite recup�rer dans mon code C#.

    Soyez indulgent...

    Voici le code C++

    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
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    // NativeDll.cpp*: définit les fonctions exportées pour l'application DLL.
    #include "stdafx.h"
    #include <windows.h>
     
    #define NATIVEDLL_API extern "C" __declspec(dllexport) 
    typedef void (* FPCallback)(int code);
     
    HHOOK hookCbt = NULL;  //Identificateur hook cbt
    HINSTANCE appInstance = NULL;  //pointeur sur instance
    FPCallback fCallback = NULL;
     
    LRESULT CALLBACK CbtHookCallback(int code, WPARAM wparam, LPARAM lparam);
     
    // Point d'entrée de la Dll
    BOOL APIENTRY DllMain(HMODULE hModule, DWORD  ul_reason_for_call, LPVOID lpReserved)
    {
    	switch (ul_reason_for_call)
    	{
    		case DLL_PROCESS_ATTACH:
    			if(appInstance == NULL) appInstance = hModule;
    			break;
    		case DLL_THREAD_ATTACH:
    			break;
    		case DLL_THREAD_DETACH:
    			break;
    		case DLL_PROCESS_DETACH:
    			break;
    	}
    	return TRUE;
    }
     
    NATIVEDLL_API bool Init(FPCallback callback)
    {
    	hookCbt = SetWindowsHookEx(WH_CBT,(HOOKPROC)CbtHookCallback, appInstance, 0);
    	fCallback = callback;
    	return (hookCbt != NULL);
    }
     
    NATIVEDLL_API void Uninit()
    {
    	if (hookCbt != NULL)
    		UnhookWindowsHookEx(hookCbt); // Arrêt du hook CBT 
    	hookCbt = NULL;
    	fCallback = NULL;
    }
     
    LRESULT CALLBACK CbtHookCallback(int code, WPARAM wparam, LPARAM lparam)
    {
    	if (code >= 0) 
    		fCallback(code);
    	return CallNextHookEx(hookCbt, code, wparam, lparam); // Rappel du hook
    }
    Et le code C# de la form :

    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
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    using System;
    using System.Windows.Forms;
    using System.Runtime.InteropServices;
     
    namespace Test
    {
        public enum WH_CBT : int
        {
            WH_CBT_MOVESIZE = 0,
            WH_CBT_MINMAX,
            WH_CBT_QS,
            WH_CBT_CREATEWND,
            WH_CBT_DESTROYWND,
            WH_CBT_ACTIVATE,
            WH_CBT_CLICKSKIPPED,
            WH_CBT_KEYSKIPPED,
            WH_CBT_SYSCOMMAND,
            WH_CBT_SETFOCUS
        }
     
        public partial class Form1 : Form
        {
            [UnmanagedFunctionPointer(CallingConvention.Cdecl)]        
            public delegate void OnHookCbtEvent(int code);
     
            [DllImport("NativeDll.dll", CallingConvention = CallingConvention.Cdecl)]
            static extern bool Init([MarshalAs(UnmanagedType.FunctionPtr)]OnHookCbtEvent cbt);
     
            [DllImport("NativeDll.dll", CallingConvention = CallingConvention.Cdecl)]
            static extern void Uninit();
     
            [MarshalAs(UnmanagedType.FunctionPtr)]
            private OnHookCbtEvent onCbt;
     
            public Form1()
            {
                InitializeComponent();
                this.onCbt = new OnHookCbtEvent(OnCbtDelegate);
                Init(onCbt);
            }
     
            public void OnCbtDelegate(int code)
            {
                listBox1.Items.Add(Enum.GetName(typeof(WH_CBT), (WH_CBT)code));
            }
     
            private void Form1_FormClosing(object sender, FormClosingEventArgs e)
            {
                Uninit();
            }
        }
    }
    Le probleme est qu'a l'ex�cution le code fonctionne mais pas longtemps, au bout d'un moment le callback n'est plus appell�. Auriez vous une id�e ?

    Merci de m'aider.

  2. #2
    Expert confirm�
    Avatar de smyley
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    6 270
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 6 270
    Par d�faut
    Je pense que le [MarshalAs(UnmanagedType.FunctionPtr)] de private OnHookCbtEvent onCbt n'est pas n�cessaire.

    Citation Envoy� par railarmenien Voir le message
    Le probleme est qu'a l'ex�cution le code fonctionne mais pas longtemps, au bout d'un moment le callback n'est plus appell�.
    �a voudrait peut �tre dire que ton d�l�gu� s'est fait collect� par le GC, mais en m�me temps vu que tu as une variable onCbt �a ne devrait pas �tre le cas ...
    Juste pour v�rifier, tu pourrai appeler, juste apr�s ton Init pour voir ce que �a fait :
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    GC.Collect();
    GC.WaitForPendingFinalizers();
    ?

  3. #3
    Futur Membre du Club
    Profil pro
    Inscrit en
    D�cembre 2009
    Messages
    4
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : D�cembre 2009
    Messages : 4
    Par d�faut
    Je pense aussi que mon callback s'est fait collecter part le GC. Mais je ne comprends pas pourquoi.

    Sinon j'ai essay�
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
     
    GC.Collect();
    GC.WaitForPendingFinalizers();
    apr�s l'appel a init() mais ca ne change rien.



    Pour info, j'ai essay� d'installer et de desinstaller le hook grace a des clics de boutons. A ce moment la le callback est appell� un peu plus longtemps mais semble tout de m�me collect� rapidement par le GC. Ce que je ne comprends pas c'est que j' ai une instance de ce d�l�gu�e priv�e dans ma Form donc je devrais en th�orie la conserver durant toute l'ex�cution.

  4. #4
    Expert confirm�
    Avatar de smyley
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    6 270
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 6 270
    Par d�faut
    et avec Marshal.GetFunctionPointerForDelegate ?

  5. #5
    Futur Membre du Club
    Profil pro
    Inscrit en
    D�cembre 2009
    Messages
    4
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : D�cembre 2009
    Messages : 4
    Par d�faut
    Je ne sais pas ou placer ce Marshal.GetFunctionPointerForDelegate()

    - C'est la premi�re fois que je 'amuse avec le marshalling en fait ^^ etje balise un peu au petit bonheur la chance. J'ai dailleurs retirer l'attribut [(MarshallAs(Unmanagedtype.FunctionPtr)] du membre priv� onCbt comme conseill� plus haut.

  6. #6
    Futur Membre du Club
    Profil pro
    Inscrit en
    D�cembre 2009
    Messages
    4
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : D�cembre 2009
    Messages : 4
    Par d�faut Suppression de "up" du message
    Concernant Marshal.GetFunctionPointerForDelegate, si je l'utilise je ne sais pas quel prototype conserver pour l'import de la fonction Init dans le code C#
    soit
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
     
    [DllImport("NativeDll.dll", CallingConvention = CallingConvention.Cdecl)]
            static extern bool Init(OnHookCbtEvent cbt);
    soit
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
     
    [DllImport("NativeDll.dll", CallingConvention = CallingConvention.Cdecl)]
            static extern bool Init(IntPtr cbt);//IntPtr correspond au type retourné par Marshal.GetFunctionPointerForDelegate.
    Quelqu'un aurait il le correctif � apporter � mon code ou un exemple avec le m�me type d'impl�mentation ( callback C# appell� dans une fonction d'une dll C++ non manag�e) ?

Discussions similaires

  1. R�ponses: 4
    Dernier message: 11/10/2011, 14h34
  2. R�ponses: 2
    Dernier message: 13/03/2009, 11h11
  3. utiliser un callback C++ natif avec du code .NET (en C#)
    Par nicolasflasque dans le forum C++/CLI
    R�ponses: 3
    Dernier message: 28/11/2008, 11h58
  4. R�ponses: 2
    Dernier message: 26/06/2007, 17h46
  5. DLL Native chargeant et appelant du code dans une DLL.NET
    Par cinemania dans le forum C++/CLI
    R�ponses: 3
    Dernier message: 17/04/2007, 07h12

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