J'ai une DLL que j'emballe pour que je puisse l'appeler à partir de C#. Une fonction utilise des événements pour vous avertir quand un état a changé, et la détermination de faire face à cela a pris un peu de creuser. Cela semble fonctionner, mais je suis curieux de savoir si quelqu'un a plus d'expérience dans ce domaine que moi et peut vous conseiller.C# et E/S chevauchées natives
La fonction est définie dans le fichier .h de la dll comme:
int NotifyStateChange(OVERLAPPED *overlapped);
typedef int (*NOTIFY_STATE_CHANGE_PROC)(OVERLAPPED *);
Exemple de code C l'appelant:
OVERLAPPED overlapped;
overlapped.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
fns.NotifyStateChange(&overlapped);
WaitForSingleObject(overlapped.hEvent, INFINITE);
// ...query for the new state or whatever...
Voici comment je l'ai approché en C#:
[DllImport("myfuncs.dll")]
unsafe public static extern int NotifyStateChange(NativeOverlapped* lpOverlapped);
static private ManualResetEvent m_stateChangeEvent = new ManualResetEvent(false);
public static DeviceState WaitForStateChange()
{
unsafe
{
Overlapped overlapped = new Overlapped(0, 0,
m_stateChangeEvent.SafeWaitHandle.DangerousGetHandle(), null);
IOCompletionCallback callback = StateChangeCallback;
byte[] userData = new byte[100];
NativeOverlapped* nativeOverlapped = overlapped.Pack(callback, userData);
NotifyStateChange(nativeOverlapped);
m_stateChangeEvent.WaitOne();
Overlapped.Unpack(nativeOverlapped);
Overlapped.Free(nativeOverlapped);
}
return GetCurrentState();
}
[ComVisibleAttribute(true)]
unsafe static public void StateChangeCallback (
uint errorCode,
uint bytesTransferred,
NativeOverlapped* overlapped)
{
m_stateChangeEvent.Set();
}
Une chose que je ne comprends pas, c'est le besoin de userData. NotifyStateChange ne déclenche qu'un événement, il ne renvoie aucune donnée. Le passage d'une valeur null UserData à Pack() semble fonctionner correctement, mais je crains que quelque chose ne se passe avec UserData sous les couvertures dont je ne suis pas conscient.
J'apprécie n'importe quel conseil sur s'il y a une manière plus appropriée de faire ceci.
Eric
la DLL elle-même accepte donc une structure et CHEVAUCHEMENT informera le hEvent sur elle en cas de changement d'état? Puis-je dire que c'est très inhabituel. Il pourrait simplement accepter un handle d'événement et le notifier, plutôt que d'exiger une structure conçue pour les E/S ... –
Oui, oui, oui et oui. Je n'ai pas écrit l'original ... –