Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/286.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#和本机重叠I/O_C#_Pinvoke_Overlapped Io - Fatal编程技术网

C#和本机重叠I/O

C#和本机重叠I/O,c#,pinvoke,overlapped-io,C#,Pinvoke,Overlapped Io,我有一个正在包装的C dll,以便可以从C#调用它。其中一个函数使用事件来通知您某个状态发生了变化,而要解决这个问题需要一些挖掘。它似乎工作正常,但我很好奇是否有人比我有更多的经验,可以提供任何建议 该函数在dll的.h文件中定义为: int NotifyStateChange(OVERLAPPED *overlapped); typedef int (*NOTIFY_STATE_CHANGE_PROC)(OVERLAPPED *); 调用它的示例C代码: OVERLAPPED ove

我有一个正在包装的C dll,以便可以从C#调用它。其中一个函数使用事件来通知您某个状态发生了变化,而要解决这个问题需要一些挖掘。它似乎工作正常,但我很好奇是否有人比我有更多的经验,可以提供任何建议

该函数在dll的.h文件中定义为:

int NotifyStateChange(OVERLAPPED *overlapped);  
typedef int (*NOTIFY_STATE_CHANGE_PROC)(OVERLAPPED *);  
调用它的示例C代码:

OVERLAPPED overlapped;  
overlapped.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);  
fns.NotifyStateChange(&overlapped);  
WaitForSingleObject(overlapped.hEvent, INFINITE);  
// ...query for the new state or whatever...
这就是我在C#中的做法:

我不清楚的一点是对用户数据的需求。NotifyStateChange只触发一个事件,不返回任何数据。将null userData传递给Pack()似乎工作得很好,但我担心userData在我不知道的情况下可能发生了一些事情

如果有更合适的方法,我非常感谢你的建议


Eric

似乎DLL设计人员出于任何原因决定使用超链接结构,而他们可以简单地使用事件的简单句柄来发送信号。显然,他们不希望查看重叠结构中的其他字段,因为DLL似乎不使用它来使用重叠数据(指针和偏移量)执行任何类型的I/O操作。因此,在不太了解所述DLL的情况下,您的使用似乎是正确的,您可以传递nil表示数据,传递0表示偏移量

但请记住,这只是一个猜测。如果可能,请联系DLL作者并要求澄清他们忽略指针和偏移量的假设是否正确


顺便说一下,如果您要得到回调,我不会阻止等待状态更改的线程。只需使用回调来处理事件(状态更改),系统的伸缩性就会更好。

您已经在阻塞事件句柄,不需要使用重叠类和回调。您只需将NativeOverlapped.EventHandle成员设置为DangerousGetHandle()返回值。DLL将设置事件


另外,将NotifyStateChange的参数声明为ref而不是指针,这样可以避免使用不安全的关键字。

啊,是的-这正是我提出这些难题的原因。现在看来很明显。下面是简化的代码

    [DllImport("myfuncs.dll")]
    public static extern int NotifyStateChange(ref NativeOverlapped lpOverlapped);

    public static DeviceState WaitForStateChange()
    {
        ManualResetEvent stateChangeEvent = new ManualResetEvent(false);
        NativeOverlapped nativeOverlapped = new NativeOverlapped();
        nativeOverlapped.EventHandle = 
            stateChangeEvent.SafeWaitHandle.DangerousGetHandle();
        NotifyStateChange(ref nativeOverlapped);
        stateChangeEvent.WaitOne();

        return GetCurrentState();
    }
谢谢


Eric

那么DLL本身接受重叠结构,并在状态更改时通知其上的hEvent?我可以说这是非常不寻常的。它可以简单地接受一个事件句柄并通知它,而不需要为I/O设计一个结构……是的,是的,是的,是的。我没有写原件。。。
    [DllImport("myfuncs.dll")]
    public static extern int NotifyStateChange(ref NativeOverlapped lpOverlapped);

    public static DeviceState WaitForStateChange()
    {
        ManualResetEvent stateChangeEvent = new ManualResetEvent(false);
        NativeOverlapped nativeOverlapped = new NativeOverlapped();
        nativeOverlapped.EventHandle = 
            stateChangeEvent.SafeWaitHandle.DangerousGetHandle();
        NotifyStateChange(ref nativeOverlapped);
        stateChangeEvent.WaitOne();

        return GetCurrentState();
    }