我正在尝试开发一种与电子卡通信的功能。我需要使用readFile()函数:
[DllImport("kernel32.dll", SetLastError = true)]
static extern bool ReadFile(IntPtr hFile, ref byte lpBuffer,
uint nNumberOfBytesToRead, out uint lpNumberOfBytesRead, Overlapped lpOverlapped);
我的功能是:
EventObject = CreateEvent(IntPtr.Zero,true,true,"");
lastError = Marshal.GetLastWin32Error();
HIDOverlapped = new System.Threading.Overlapped();
HIDOverlapped.OffsetLow = 0;
HIDOverlapped.OffsetHigh = 0;
HIDOverlapped.EventHandleIntPtr = EventObject;
readHandle = CreateFile(MyDeviceInterfaceDetailData.DevicePath, (GENERIC_READ | GENERIC_WRITE), (FILE_SHARE_READ | FILE_SHARE_WRITE), IntPtr.Zero, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, IntPtr.Zero);
uint numberOfBytesRead;
readBuffer= new byte[8];
string byteValue;
bool result = ReadFile(readHandle, ref readBuffer[0], (uint)capabilities.InputReportByteLength, out numberOfBytesRead, HIDOverlapped);
lastError = Marshal.GetLastWin32Error(); //Problem
最后一行中的函数Marshal.GetLastWin32Error()
返回错误代码997.
在第二段中,代码0xc0000005(FatalExecutionEngineError)出现另一个错误,软件崩溃。
你知道我能尝试什么吗?
答案 0 :(得分:4)
这是不问题。
错误代码997为ERROR_IO_PENDING
,这是ReadFile
在开始重叠读取时将返回的内容。
来自docs:
注意GetLastError代码ERROR_IO_PENDING不是失败;它指定读取操作异步完成等待完成。有关更多信息,请参阅备注。
说明:
ReadFile可能在读取操作完成之前返回。在这种情况下,ReadFile返回FALSE,GetLastError函数返回ERROR_IO_PENDING,这允许在系统完成读取操作时继续调用进程。
使用重叠I / O是一项要求吗?
使用此功能定义:
[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
public static extern SafeFileHandle CreateFile(string lpFileName, uint dwDesiredAccess, uint dwShareMode, IntPtr lpSecurityAttributes, uint dwCreationDisposition, uint dwFlagsAndAttributes, IntPtr hTemplateFile);
您可以从使用Win API打开的文件中创建常规FileStream
:
var fileHandle = CreateFile(.....);
if (fileHandle.IsInvalid)
Marshal.ThrowExceptionForHR(Marshal.GetHRForLastWin32Error());
// The last parameter of the FileStream constructor (isAsync) will make the class use async I/O
using (var stream = new FileStream(fileHandle, FileAccess.ReadWrite, 4096, true))
{
var buffer = new byte[4096];
// Asynchronously read 4kb
var bytesRead = await stream.ReadAsync(buffer, 0, buffer.Length);
}
答案 1 :(得分:0)
直接来自MSDN:
因为读取操作从指定的偏移量开始 OVERLAPPED结构和ReadFile可能会在之前返回 系统级读操作完成(读取待处理),既不是 偏移或结构的任何其他部分都应该被修改,释放, 或者由应用程序重用,直到事件发出信号(即, 读完了)。
如果您阅读链接页面,您会发现如果您传递除null
以外的任何内容作为lpOverlapped参数,那么它将是异步调用,因此您的问题很可能来自于您尝试使用的事实在函数设置之前的readBuffer
- 或换句话说:在读取完成之前。
正如Lucas已经在他的回答中指出的那样,当操作正在进行时,最后一个错误将返回997,因此这是所需的输出。