来自 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);