2016-01-13 86 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 
相關問題