2016-01-13 48 views
0

我一直在这个项目上工作了一个星期左右,并在本周开始,我的ReadFile返回一个AccessViolationException - “试图读取或写入受保护的内存。”所以我玩了一下,然后就消失了。我以为我修好了,但可能不是?现在我的WriteFile抛出了一个FatalExecutionEngineError,经过一番阅读后,似乎两个事件可能是相关的;虽然我不确定。这里是我的声明,有可能是这些问题:vb.net AccessViolationException和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,但没有起作用,于是我将应用程序转移到另一台机器上,看看它是否能在那里工作,而不是。第二台机器与第一台机器相同。我不知道该从哪里出发。

+0

凡'mabtRxBuf'声明?是否有可能被两个线程同时修改? –

+0

我会推荐看看[pinvoke](http://www.pinvoke.net/default.aspx/kernel32.readfile)网站,以确保你有推荐的签名。我注意到你正在用''ReadFile''和''Integer''来声明缓冲区的'IntPtr'参数。另外,在调用它时,pinvoke站点建议使用'Marshal.AllocHGlobal'来获取指向缓​​冲区的指针。我不确定这是你问题的原因,但我也不会感到惊讶。 –

+0

除了缺少IntPtr外没有什么大声喊叫,水晶球说你没有正确声明DCB或COMMTIMEOUTS。在这种情况下调用GetCommState()或GetCommTimeouts()会损坏堆。这*最终会导致这次崩溃。只是不要这样做,请改用SerialPort类。 –

回答

0

该结束了工作为我的代码:

 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 
相关问题