2012-11-07 2 views
0

스택 트레이스를 알아낼 질수 : mscorlib에이 NullReferenceException이

나는 반사에 대한 목표 소스 무언가에 볼

: System.Threading._IOCompletionCallback.PerformIOCompletionCallback (UINT32의 errorCode, UINT32하는 numBytes, NativeOverlapped * pOVERLAP) 소스에서. 그래서 나는 반사를 사용하는 아주 적은 양의 코드를 게시 할 것입니다.

나는 보통 NullReferenceExceptions를 쉽게 찾을 수 있습니다. 이 코드는 내 코드로 보이지 않지만 내 목숨을 구하기 위해 알아낼 수는 없습니다. 나는 VB.net에서이 코드 봇을 가지고 있고 C# .Net은 모두 같은 문제가있다. 내 문제는 내 포인터가 작동하는 방법에 있다고 생각하지만 잘못 될 수 있습니다.

코드는 직설적입니다. 나는 COM 모드에있는 USB를 통해 연결된 바코드 스캐너가 있습니다. 완벽하게 작동하는이 바코드를 사용하는 다른 프로그램의 일부 코드를 복사했습니다. 그러나 그것이하는 일을 정리하면 열리는 것입니다. 그러면 반사를 사용하여 포인터를 열린 COM 포트로 가져 와서 DataEventListener를 설정합니다. 내가 100ms를 기다렸다가 뭔가를 스캔하면 문자열 형태로 데이터를 뱉어 낸다. 단순한 수 있습니다. 내 코드와 flawlesly 작품의 다른 하나의 차이점은 내가 포인터를 가져야한다는 것입니다. 내 스캐너를 켜려면 IntPtr을 사용하여 comport에 대한 포인터가 필요합니다. C# 나는 IntPtr을 사용하는데, VB에서는 SafeFileHandle을 사용한다. 둘 다 같은 오류가 있습니다. 오류가 발생하는 유일한 시간은 데이터 이벤트가 발생하는 경우입니다. 이것이 내가 손잡이와 함께 있어야한다고 생각하는 이유입니다. 이상한 점은 촬영기를 켜고 끄기 위해 핸들이 필요하다는 것입니다. 그래서 나는 유효한 핸들을 가지고 있다는 것을 알고 있습니다. (단지에 개최되는 경우) 모르겠어요 그럼 누구든지 어떤 도움이나 자원이 오류가 발생하는 데 관해서는 무엇입니까?

첫번째로 .. VB.NET 공공 클래스 ImagerOposDevice 상속 AbstractOPOSDevice 희미한 PortHandle SafeFileHandle 희미한 ImagerPort으로하여 SerialPort로 공공 ExitCode를 = 1 하위 새로운 (문자열로 ByVal의 comName) ImagerPort = 새로운하여 SerialPort (comName) 내 주요 형태

Protected Overrides Function Open() As Boolean 
    ImagerPort.Open() 
    PortHandle = GetHandleFromSerialPort(ImagerPort) 

    If Not PortHandle.IsInvalid Then 
     AddHandler ImagerPort.DataReceived, AddressOf DataReceivedHandler 
    End If 

    Return (Not PortHandle.IsInvalid) 
End Function 
Protected Overrides Sub Close() 
    Try 
     ImagerPort.Close() 
     ImagerPort.Dispose() 
    Catch ex As Exception 
     Console.WriteLine(ex.Message) 
     Console.ReadLine() 
    End Try 

End Sub 

Protected Overrides Function RunCommand(ByVal X As Integer) As Boolean 
    If X = 0 Then 
     Return TurnImagerOn() 
    ElseIf X = 1 Then 
     Return TurnImagerOff() 
    Else 
     Return False 
    End If 
End Function 

Private Shared Function GetHandleFromSerialPort(ByVal sp As SerialPort) As SafeFileHandle 
    Dim BaseStream As Object = sp.BaseStream 
    Dim BaseStreamType As Type = BaseStream.GetType 
    Return BaseStreamType.GetField("_handle", BindingFlags.NonPublic Or BindingFlags.Instance).GetValue(BaseStream) 
End Function 
Private Sub DataReceivedHandler(ByVal sender As Object, ByVal e As SerialDataReceivedEventArgs) 
    Try 
     'Dim sp As SerialPort = CType(sender, SerialPort) 
     System.Threading.Thread.Sleep(100) 
     Dim len = ImagerPort.BytesToRead 
     Dim buffer(len - 1) As Byte 
     ImagerPort.Read(buffer, 0, len) 

     Dim indata As String = System.Text.ASCIIEncoding.ASCII.GetString(buffer) 
     Console.WriteLine("Data Received:") 
     Console.Write(indata) 
     TurnImagerOff() 
    Catch ex As Exception 
     Console.WriteLine(ex.Message) 
    End Try 
    exitCode = 0 
End Sub 

하위 끝은 곧장 앞으로

,259,528,952,732입니다 10

이제 C# 코드입니다. 그것은 창문 형태이지만 개념은 거의 동일합니다.

private SerialPort devicePort; 
    private IntPtr deviceHandle; 
    public Imager(string Port) : base() 
    { 
     devicePort = new SerialPort(Port); 
    } 
    protected override bool Open() 
    { 
     try 
     { 
      devicePort.Open(); 
      deviceHandle = GetHandleFromSerialPort(devicePort); 
      Console.WriteLine("Device Handle:{0}", deviceHandle); 
      Console.WriteLine("Device Open:{0}", devicePort.IsOpen); 
     } 
     catch(Exception ex) 
     { 
      Console.WriteLine(ex.Message); 
     } 
     return devicePort.IsOpen; 
    } 
    protected override bool Close() 
    { 
      devicePort.Close(); 
      devicePort.Dispose(); 
     return true; 
    } 
    protected override CommandReturnCodes RunCommand(int command) 
    { 
     switch (command) 
     { 
      case 0: 
       TurnImagerOn(); 
       break; 
      case 1: 
       TurnImagerOff(); 
       break; 
      case 2: 
       ReadLatch(); 
       break; 
      case 3: 
       GetPartNumber(); 
       break; 
      case 4: 
       GetSerialNumber(); 
       break; 
      case 5: 
       GetProductString(); 
       break; 
      default: 
       return CommandReturnCodes.FAIL; 
     } 
     return CommandReturnCodes.SUCCESS; 
    } 
    private static IntPtr GetHandleFromSerialPort(SerialPort sp) 
    { 
     Type t = typeof(SerialPort); 
     BindingFlags bf = BindingFlags.Instance | BindingFlags.NonPublic; 
     FieldInfo fi = t.GetField("internalSerialStream", bf); 
     object ss = fi.GetValue(sp); 
     Type t2 = fi.FieldType; 
     FieldInfo fi2 = t2.GetField("_handle", bf); 
     SafeFileHandle _handle = (SafeFileHandle)fi2.GetValue(ss); 
     Type t3 = typeof(SafeFileHandle); 
     FieldInfo fi3 = t3.GetField("handle", bf); 
     IntPtr handle = (IntPtr)fi3.GetValue(_handle); 
     return handle; 
    } 
    public void TurnOnImagerEventListener() 
    { 
     devicePort.DataReceived += new SerialDataReceivedEventHandler(devicePort_DataReceived); 
    } 

    void devicePort_DataReceived(object sender, SerialDataReceivedEventArgs e) 
    { 
     System.Threading.Thread.Sleep(100); 
     SerialPort imager = sender as SerialPort; 
     byte[] buffer = new byte[imager.BytesToRead]; 
     imager.Read(buffer, 0, imager.BytesToRead); 
     var scannedText = System.Text.Encoding.ASCII.GetString(buffer).Trim(); 
     SendBarcodeEvent(scannedText); 
     TurnImagerOff(); 
     Console.WriteLine(scannedText); 
    } 

하고 전화는 같은 일을하다

 im = new Imager(comportBox.Text); 
     im.OpenDevice(); 
     im.TurnOnImagerEventListener(); 
     im.BarcodeScanned += new DataAvailableHandler(DeviceInformationReceived); 
+1

그리고 ... 어떤 줄에 주장합니까? – LightStriker

+0

당신은 예외를 의미합니까 .. 그게 문제입니다, 그건 아닙니다. 그럴 수있는 바렌입니다. 나는 솔직히 그것이 내가 손을 잡는 길에있다. 그리고 다른 누군가의 핸들 코드를 복사 한 이후로 불행하게도 그 부분을 이해하지 못합니다. –

+1

중단 점을 넣고 줄 단위로 시도 했습니까? – LightStriker

답변

0

음이 LightStriker 나 어제 저를 눈 멀게 한이 안개 과거의 참조 도움 것으로 나타났다. 나는 여전히 vb.net 버전이 작동하지 않지만 그것이 끝나면 결국 C# 프로그램에 사용 된 IntPtr이 별도의 스레드 (IE 데이터 이벤트)가 호출 될 때 유지되지 않는다는 것이 었습니다. 데이터 이벤트 부분을 밟았을 때 TurnImagerOff() 부분을 호출 할 때까지 실패하지 않았습니다. 그것은 쉬운 일이었습니다. 제가해야 할 일은 시리얼 포트와 내 IntPtr을 모두 정적 멤버로 변경하는 것이 었습니다. VB.net 코드에서 시도해 보았지만 ... 분명히 나는 ​​그것을 파악할만큼 똑똑하지 않습니다. 오 잘 오늘은 또 다른 날이며 내 코드의 적어도 50 %가 작동합니다.

null 참조 오류가있어 어디서나 찾을 수없는 사용자 분들께. 그리고 스택 추적은 줄 번호를 알려주지 않습니다. 포인터 인 멤버를 호출하는 다른 스레드에서 실행중인 것을 확인하십시오. (또는 포인터로 반영). 데이터 이벤트, 스레드 풀, 배경 작업자, 타이머, 위임자 등을 확인하십시오. 내 어리 석음이 다른 사람을 도울 것이라고 기대합니다.

관련 문제