I have a C dll that I'm wrapping so that I can call it from C#. One function uses events to notify you when a state has changed, and figuring out to deal with it took some digging. It seems to be working ok, but I'm curious if anyone has more experience with this than I do and can offer any advice.
The function is defined in the dll's .h file as:
int NotifyStateChange(OVERLAPPED *overlapped);
typedef int (*NOTIFY_STATE_CHANGE_PROC)(OVERLAPPED *);
Sample C code calling it:
OVERLAPPED overlapped;
overlapped.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
fns.NotifyStateChange(&overlapped);
WaitForSingleObject(overlapped.hEvent, INFINITE);
// ...query for the new state or whatever...
This is how I approached it in 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();
}
One thing I'm unclear on is the need for userData. NotifyStateChange just fires an event, it doesn't return any data. Passing a null userData to Pack() seemed to work fine, but I'm concerned something may be going on with userData under the covers that I'm not aware of.
I appreciate any advice on if there's a more proper way to do this.
Eric