代码之家  ›  专栏  ›  技术社区  ›  Logan

vb.net AccessViolationException和FatalExecutionEngineError

  •  0
  • Logan  · 技术社区  · 9 年前

    我已经在这个项目上工作了一周左右,在本周初,我的ReadFile返回了一个AccessViolationException-“试图读取或写入受保护的内存”。所以我玩了一会儿,它就消失了。我以为我修好了,但也许没有?现在我的WriteFile抛出了一个FatalExecutionEngineError,经过一些阅读,这两个事件似乎有关联;但我不确定。以下是我的声明,这些声明可能有问题:

        <DllImport("kernel32.dll")> Private Shared Function CloseHandle(
        ByVal hObject As Integer) As Integer
    End Function
    
    <DllImport("kernel32.dll")> Private Shared Function CreateFile(
        <MarshalAs(UnmanagedType.LPStr)> ByVal lpFileName As String,
        ByVal dwDesiredAccess As Integer, ByVal dwShareMode As Integer,
        ByVal lpSecurityAttributes As Integer,
        ByVal dwCreationDisposition As Integer,
        ByVal dwFlagsAndAttributes As Integer,
        ByVal hTemplateFile As Integer) As Integer
    End Function
    
    <DllImport("kernel32.dll")> Private Shared Function GetCommState(
        ByVal hCommDev As Integer, ByRef lpDCB As DCB) As Integer
    End Function
    
    <DllImport("kernel32.dll")> Private Shared Function GetCommTimeouts(
        ByVal hFile As Integer, ByRef lpCommTimeouts As COMMTIMEOUTS) As Integer
    End Function
    
    <DllImport("kernel32.dll")> Private Shared Function GetLastError() As Integer
    End Function
    
    <DllImport("kernel32.dll")> Private Shared Function PurgeComm(
        ByVal hFile As Integer, ByVal dwFlags As Integer) As Integer
    End Function
    
    <DllImport("kernel32.dll")> Private Shared Function ReadFile(
        ByVal hFile As Integer, ByVal Buffer As Byte(),
        ByVal nNumberOfBytesToRead As Integer,
        ByRef lpNumberOfBytesRead As Integer,
        ByRef lpOverlapped As Overlapped) As Integer
    End Function
    
    <DllImport("kernel32.dll")> Private Shared Function SetCommTimeouts(
        ByVal hFile As Integer, ByRef lpCommTimeouts As COMMTIMEOUTS) As Integer
    End Function
    
    <DllImport("kernel32.dll")> Private Shared Function SetCommState(
        ByVal hCommDev As Integer, ByRef lpDCB As DCB) As Integer
    End Function
    
    <DllImport("kernel32.dll")> Private Shared Function WriteFile(
        ByVal hFile As Integer, ByVal Buffer As Byte(),
        ByVal nNumberOfBytesToWrite As Integer,
        ByRef lpNumberOfBytesWritten As Integer,
        ByRef lpOverlapped As Overlapped) As Integer
    End Function
    
    <DllImport("kernel32.dll")> Private Shared Function SetCommMask(
        ByVal hFile As Integer,
        ByVal dwEvtMask As Integer) As Integer
    End Function
    
    <DllImport("kernel32.dll", SetLastError:=True)> Private Shared Function WaitCommEvent(
        ByVal hFile As Integer,
        ByRef mask As Integer,
        ByRef lpOverlap As Overlapped) As Integer
    End Function
    
    <DllImport("kernel32.dll")> Private Shared Function FormatMessage(
        ByVal dwFlags As Integer,
        ByVal lpSource As Integer,
        ByVal dwMessageId As Integer,
        ByVal dwLanguageId As Integer,
        ByVal lpBuffer As StringBuilder,
        ByVal nSize As Integer,
        ByVal Arguments As Integer) As Integer
    End Function
    

    下面是最初导致AccessViolationException的代码,该代码消失了:

    Private Function read() As String
        Dim sErrTxt As String
        Dim iReadChars, iRc As Integer
    
        If mhRS <> INVALID_HANDLE_VALUE Then
            ' Sets Comm Mask
            iRc = SetCommMask(mhRS, EventMasks.RxChar)
            If iRc <> 0 Then
                'Waits for a comm event
                iRc = WaitCommEvent(mhRS, miEvtMask, Nothing)
                If iRc <> 0 Then
                    miStringSize = 0
                    miString = ""
                    ReDim mabtRxBuf(miBufferSize)
                    ' Loop through the buffer and store it in a string while there is still chars in the buffer
                    For i As Integer = 0 To 20
                        iRc = ReadFile(mhRS, mabtRxBuf, miBufferSize, iReadChars, Nothing)
                        If iRc <> 0 Then
                            ' Stores the size of the string read and forms the string
                            If iReadChars > 0 Then
                                miStringSize += iReadChars
                                miString &= defaultEncoding.GetString(mabtRxBuf)
                            End If
                        Else
                            ' Read Error 
                            sErrTxt = pErr2Text(GetLastError())
                            MsgBox("ReadFile failed " & sErrTxt)
                            Return Nothing
                        End If
                    Next
                    'Loop While iReadChars > 0
                    ' Returns the concantenated string
                    Return miString
                Else
                    ' Handles WaitCommEvent error
                    sErrTxt = pErr2Text(GetLastError())
                    MsgBox("WaitCommEvent failed " & sErrTxt)
                    Return Nothing
                End If
            Else
                ' Handles SetSommMask error
                sErrTxt = pErr2Text(GetLastError())
                MsgBox("Unable to SetCommMask " & sErrTxt)
                Return Nothing
            End If
    
        Else
            ' Handles port not open error
            MsgBox("Please initialize port first")
            Return Nothing
        End If
    End Function
    

    最后,下面是导致FatalExecutionEngineError的代码:

    Private Sub write(ByVal byteBuff As Byte())
        Dim sErrTxt As String
        Dim bytesSent = 0, iRc, iWriteChars As Integer
    
        If mhRS <> INVALID_HANDLE_VALUE Then
            ' Writes the passed Byte() to the comm port
            iRc = WriteFile(mhRS, byteBuff, byteBuff.Length, iWriteChars, Nothing)
            If iRc = 0 Then
                ' Handles WriteFile error
                sErrTxt = pErr2Text(GetLastError())
                MsgBox("WriteFile Failed " & sErrTxt)
            End If
        Else
            ' Handles port not open error
            MsgBox("Please initialize port first")
            Exit Sub
        End If
    End Sub
    

    我在windows 7 64位上使用visual studio 2015和.NET 4.6.1。我重新安装了.net,但它不起作用,所以我将应用程序转移到另一台机器上,看看它是否在那里起作用,但没有。第二台机器与第一台相同。我不知道从这里往哪里走。

    1 回复  |  直到 9 年前
        1
  •  0
  •   Logan    9 年前

    最终对我有用的代码是:

            Private receivedText As String
    
    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        With miPort
            .PortName = "COM3"
            .BaudRate = 38400
            .Parity = Parity.None
            .StopBits = StopBits.One
            .DataBits = 8
            .DtrEnable = True
            .RtsEnable = True
            .Handshake = Handshake.None
            .Encoding = Encoding.GetEncoding(28591)
        End With
    End Sub
    
    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        If Not miPort.IsOpen Then
            miPort.Open()
        End If
    
        If miPort.IsOpen Then
            miPort.Write(toCharacters("55FF0510030004BC0105010189D1"))
        End If
    End Sub
    
    ' Converts the passed string as hexidecimal numbers to its characters
    Private Function toCharacters(ByVal hexText As String) As String
        Dim num As String
        Dim sendText As String = ""
    
        For y As Integer = 1 To Len(hexText) Step 2
            ' Takes two of the numbers passed (1 byte in Hex)
            num = Mid(hexText, y, 2)
            ' Converts the numbers into their decimal number, then to their character and stores them in a String()
            sendText &= (ChrW(Val("&h" & num)))
        Next y
    
        Return sendText
    End Function
    
    Private Sub miPort_DataReceived(sender As Object, e As SerialDataReceivedEventArgs) Handles miPort.DataReceived
        receivedText = miPort.ReadExisting()
    End Sub