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:
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:
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.
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:
1 2 3
|
[DllImport("NativeDll.dll", CallingConvention = CallingConvention.Cdecl)]
static extern bool Init(OnHookCbtEvent cbt); |
soit
Code:
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) ?