我在C#中使用WinUSB与使用批量传输的PIC4550通信,并且遇到了一个奇怪的问题。
当前代码可以正常工作,但仍然包含一些我想要删除的调试Console.Write()行,因为它们会使代码混乱。删除它们并使用调试器单步执行代码也可以正常工作。
不幸的是,当我删除调试行时,代码停止工作。结果' byte数组返回null,并抛出空引用异常。
这里发生了什么?
public static ulong GetBulkData(Device d, ref byte[] result)
{
byte _inPipe = 0x81;
ulong bufferlength = 64;
NativeOverlapped gOverlapped = new NativeOverlapped();
GCHandle pinnedOverlap = new GCHandle();
gOverlapped.InternalLow = IntPtr.Zero;
gOverlapped.InternalHigh = IntPtr.Zero;
gOverlapped.OffsetLow = 0;
gOverlapped.OffsetHigh = 0;
gOverlapped.EventHandle = Win32.CreateEvent(IntPtr.Zero, true, false, IntPtr.Zero);
pinnedOverlap = GCHandle.Alloc(gOverlapped, GCHandleType.Pinned);
ulong lengthtransferred = 0;
Array.Clear(result, 0, result.Length);
GCHandle pinnedBuffer = GCHandle.Alloc(result, GCHandleType.Pinned);
Win32.WinUsb_ReadPipe(d._handle, _inPipe, pinnedBuffer.AddrOfPinnedObject(), bufferlength, ref lengthtransferred, pinnedOverlap.AddrOfPinnedObject());
int hr = Win32.GetLastError();
bool bResult = (hr == 0);
pinnedOverlap.Free();
if (bResult)
{
foreach (byte b in result)
Console.Write(" " + b);
return lengthtransferred;
}
else
{
Console.WriteLine("USB Error Code " + hr);
uint pLength = 0;
// Deal with the error code
switch (hr)
{
case Win32.ERROR_IO_PENDING:
// Asynchronous I/O is still in progress... wait for it to complete
int evt = Win32.WaitForSingleObject(gOverlapped.EventHandle, 10);
switch (evt)
{
case Win32.WAIT_OBJECT_0:
// I/O completed.
// Check on the results of the asynchronous read and update the nBytesRead
bResult = Win32.WinUsb_GetOverlappedResult(d._handle, pinnedBuffer.AddrOfPinnedObject(), out pLength, true);
if (bResult)
{
// Success
Console.WriteLine("USB overlap received");
}
break;
case Win32.WAIT_TIMEOUT:
default:
// I/O error or timeout. Cancel outstanding I/O.
Win32.CancelIo(d._handle);
break;
}
break;
}
pinnedBuffer.Free();
return pLength;
}
}
答案 0 :(得分:0)
可以使用以下行:
foreach (byte b in result)
Console.Write(" " + b);
return lengthtransferred;
目前你只是在foreach中写入控制台,你可能还需要删除foreach循环
答案 1 :(得分:0)
解决方案,适用于后来遇到此问题的任何人。看起来这是一个时间问题。 bResult返回正确,因为传输是成功的,但信息实际上并没有进入我用GCHandle引用的字节数组。
解决方案是通过将重叠句柄更改为空指针来强制Winusb同步传输。 WinUsb_ReadPipe行已更改为:
Win32.WinUsb_ReadPipe(d._handle, _inPipe, pinnedBuffer.AddrOfPinnedObject(), bufferlength, ref lengthtransferred, IntPtr.Zero);
它完美无缺。
受this article启发