来自 USB AccessViolationException 的 C# .NET ReadFile 未处理
C# .NET ReadFile from USB AccessViolationException was unhandled
我在调用 ReadFile API 时收到 AccessViolationException
。我查看了 Whosebug 上处理类似问题的所有条目,但没有成功破译问题所在。
这里是有问题的相关代码:
调用
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern IntPtr CreateFile([MarshalAs(UnmanagedType.LPTStr)] string filename, UInt32 desiredaccess, UInt32 sharemode, IntPtr securityattributes, UInt32 creationdisposition, UInt32 flagsandattributes, IntPtr templatefile);
[DllImport("kernel32.dll", BestFitMapping = true, CharSet = CharSet.Ansi, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool ReadFile(IntPtr hFile, out byte[] lpbuffer, UInt32 nNumberofBytesToRead, out UInt32 lpNumberofBytesRead, IntPtr lpOverlapped);
[DllImport("kernel32.dll", BestFitMapping = true, CharSet = CharSet.Ansi, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool WriteFile(IntPtr hFile, byte[] lpBuffer, UInt32 nNumberOfBytesToWrite, out UInt32 lpNumberOfBytesWritten, IntPtr lpOverlapped);
创建文件函数调用
private IntPtr OpenPort(string port)
{
IntPtr printerhandle = IntPtr.Zero;
printerhandle = CreateFile(port,
(UInt32)(FileAccess.GENERIC_READ | FileAccess.GENERIC_WRITE),
(UInt32)(FileShare.FILE_SHARE_READ | FileShare.FILE_SHARE_WRITE),
IntPtr.Zero,
(UInt32)FileMode.OPEN_EXISTING,
(UInt32)(FileAttribute.FILE_ATTRIBUTE_NORMAL),
IntPtr.Zero);
return (printerhandle);
}
READFILE 函数调用
private bool WriteToPort(IntPtr printer, ref byte[] data)
{
bool success = true;
byte[] data2 = new byte[64];
byte[] dataread = new byte[64];
int index = 0;
int length = 64;
uint written = 0;
uint read = 0;
while ((index + length) <= data.Length)
{
Array.Copy(data, index, data2, 0, length);
success &= WriteFile(printer, data2, (uint)length, out written, IntPtr.Zero);
index += 64;
}
if ((index < data.Length) &&
((index + length) > data.Length))
{
length = data.Length - index;
Array.Copy(data, index, data2, 0, length);
success &= WriteFile(printer, data2, (uint)length, out written, IntPtr.Zero);
}
success &= ReadFile(printer, out dataread, 64, out read, IntPtr.Zero);
return success;
}
执行success &= ReadFile(printer, out dataread, 64, out read, IntPtr.Zero);
行时出现异常
这是 VS2013 报告的相关堆栈跟踪:
StackTrace:
at System.StubHelpers.MngdNativeArrayMarshaler.ClearNative(IntPtr pMarshalState, IntPtr pNativeHome, Int32 cElements)
at APP_NET.Main.ReadFile(IntPtr hFile, Byte[]& lpbuffer, UInt32 nNumberofBytesToRead, UInt32& lpNumberofBytesRead, IntPtr lpOverlapped)
at APP_NET.Main.WriteToPort(IntPtr printer, Byte[]& data) in Main.cs:line 770
对可能发生的事情有什么想法吗?
因为你对ReadFile
函数的声明有误。从 lpbuffer
参数中删除 out
。
读取文件导入:
[DllImport("kernel32.dll", BestFitMapping = true, CharSet = CharSet.Ansi, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool ReadFile(IntPtr hFile, byte[] lpbuffer, UInt32 nNumberofBytesToRead, out UInt32 lpNumberofBytesRead, IntPtr lpOverlapped);
正在读取文件:
success &= ReadFile(printer, dataread, 64, out read, IntPtr.Zero);
我在调用 ReadFile API 时收到 AccessViolationException
。我查看了 Whosebug 上处理类似问题的所有条目,但没有成功破译问题所在。
这里是有问题的相关代码:
调用
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern IntPtr CreateFile([MarshalAs(UnmanagedType.LPTStr)] string filename, UInt32 desiredaccess, UInt32 sharemode, IntPtr securityattributes, UInt32 creationdisposition, UInt32 flagsandattributes, IntPtr templatefile);
[DllImport("kernel32.dll", BestFitMapping = true, CharSet = CharSet.Ansi, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool ReadFile(IntPtr hFile, out byte[] lpbuffer, UInt32 nNumberofBytesToRead, out UInt32 lpNumberofBytesRead, IntPtr lpOverlapped);
[DllImport("kernel32.dll", BestFitMapping = true, CharSet = CharSet.Ansi, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool WriteFile(IntPtr hFile, byte[] lpBuffer, UInt32 nNumberOfBytesToWrite, out UInt32 lpNumberOfBytesWritten, IntPtr lpOverlapped);
创建文件函数调用
private IntPtr OpenPort(string port)
{
IntPtr printerhandle = IntPtr.Zero;
printerhandle = CreateFile(port,
(UInt32)(FileAccess.GENERIC_READ | FileAccess.GENERIC_WRITE),
(UInt32)(FileShare.FILE_SHARE_READ | FileShare.FILE_SHARE_WRITE),
IntPtr.Zero,
(UInt32)FileMode.OPEN_EXISTING,
(UInt32)(FileAttribute.FILE_ATTRIBUTE_NORMAL),
IntPtr.Zero);
return (printerhandle);
}
READFILE 函数调用
private bool WriteToPort(IntPtr printer, ref byte[] data)
{
bool success = true;
byte[] data2 = new byte[64];
byte[] dataread = new byte[64];
int index = 0;
int length = 64;
uint written = 0;
uint read = 0;
while ((index + length) <= data.Length)
{
Array.Copy(data, index, data2, 0, length);
success &= WriteFile(printer, data2, (uint)length, out written, IntPtr.Zero);
index += 64;
}
if ((index < data.Length) &&
((index + length) > data.Length))
{
length = data.Length - index;
Array.Copy(data, index, data2, 0, length);
success &= WriteFile(printer, data2, (uint)length, out written, IntPtr.Zero);
}
success &= ReadFile(printer, out dataread, 64, out read, IntPtr.Zero);
return success;
}
执行success &= ReadFile(printer, out dataread, 64, out read, IntPtr.Zero);
行时出现异常
这是 VS2013 报告的相关堆栈跟踪:
StackTrace:
at System.StubHelpers.MngdNativeArrayMarshaler.ClearNative(IntPtr pMarshalState, IntPtr pNativeHome, Int32 cElements)
at APP_NET.Main.ReadFile(IntPtr hFile, Byte[]& lpbuffer, UInt32 nNumberofBytesToRead, UInt32& lpNumberofBytesRead, IntPtr lpOverlapped)
at APP_NET.Main.WriteToPort(IntPtr printer, Byte[]& data) in Main.cs:line 770
对可能发生的事情有什么想法吗?
因为你对ReadFile
函数的声明有误。从 lpbuffer
参数中删除 out
。
读取文件导入:
[DllImport("kernel32.dll", BestFitMapping = true, CharSet = CharSet.Ansi, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool ReadFile(IntPtr hFile, byte[] lpbuffer, UInt32 nNumberofBytesToRead, out UInt32 lpNumberofBytesRead, IntPtr lpOverlapped);
正在读取文件:
success &= ReadFile(printer, dataread, 64, out read, IntPtr.Zero);