Take the 2-minute tour ×

StackTrace: at System.Threading._IOCompletionCallback.PerformIOCompletionCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* pOVERLAP) Source: mscorlib

I see in the target source something about reflection. So i'll post the very small amount of code that uses reflection.

I normally am able to find NullReferenceExceptions easily. This one though does not appear to be my code, and I can not figure it out to save my life. I have this code bot in VB.net, and C#.Net Both have the same problem. I think that my problem is in how my pointer works, but I could be wrong.

The code is straight forward. I have a barcode scanner attached via usb that is in COM mode. I copied some of my code from another program that uses this same barcode that works perfectly. But to sum up what it does is that it opens, then, by use of reflection, gets the Pointer to the open com port, sets up a DataEventListener. When I scan something i wait 100ms, then spit out the data in string form. Simple as could be. The difference between my code and the other one that works flawlesly is that I have to get the pointer. To turn on my scanner i need a pointer to the comport using IntPtr. C# I use IntPtr, in VB i use SafeFileHandle. Both have the same error. The only time the error occurs is when a data event is fired. This is why I think it has to be with the handle. What is strange is that the Handle is needed to turn on and off the imager so I know i have a valid handle. (just don't know if it is held on to) So does anyone have any help or resources as to why I am having this error?

First up.. VB.NET Public Class ImagerOposDevice Inherits AbstractOPOSDevice Dim PortHandle As SafeFileHandle Dim ImagerPort As SerialPort Public exitCode = 1 Sub New(ByVal comName As String) ImagerPort = New SerialPort(comName) End Sub

Protected Overrides Function Open() As Boolean
    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()
    Catch ex As Exception
    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()
        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)
        'Dim sp As SerialPort = CType(sender, SerialPort)
        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:")
    Catch ex As Exception
    End Try
    exitCode = 0
End Sub

in my main form it is straight forward

    imager = New ImagerOposDevice("COM7")
    For index = 1 To 100 Step 1
        If imager.exitCode = 0 Then
            Exit For
        End If
    Console.WriteLine("Press Enter to Close")

Now for the C# code. It is a windows form, but the concept is almost identicle.

    private SerialPort devicePort;
    private IntPtr deviceHandle;
    public Imager(string Port) : base()
        devicePort = new SerialPort(Port);
    protected override bool Open()
            deviceHandle = GetHandleFromSerialPort(devicePort);
            Console.WriteLine("Device Handle:{0}", deviceHandle);
            Console.WriteLine("Device Open:{0}", devicePort.IsOpen);
        catch(Exception ex)
        return devicePort.IsOpen;
    protected override bool Close()
        return true;
    protected override CommandReturnCodes RunCommand(int command)
        switch (command)
            case 0:
            case 1:
            case 2:
            case 3:
            case 4:
            case 5:
                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)
        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();

and to call it is same thing

        im = new Imager(comportBox.Text);
        im.BarcodeScanned += new DataAvailableHandler(DeviceInformationReceived);
share|improve this question
And... on what line does it assert? –  LightStriker Nov 7 '12 at 21:01
do you mean the exception.. that's the problem, it doesnt. It's as baren as could be. I honestly thing it is in the way i get my handle. And since i copied the handle code from someone else, i unfortunately don't understand that portion of code. –  Robert Snyder Nov 7 '12 at 21:05
You tried putting break points and going in line by line? –  LightStriker Nov 7 '12 at 21:06
No i didn't. I'll put one in my data event. –  Robert Snyder Nov 7 '12 at 21:07
Also, from that code, I don't see what you're doing with that handle. If SerialPort doesn't expose that, it's safe to assume you have no guaranty of getting anything valid by reflection. –  LightStriker Nov 7 '12 at 21:09
show 1 more comment

1 Answer

Well it turns out that LightStriker helped me see past this fog that was blinding me yesterday. I still don't have the vb.net version working, but what it ended up being was that the IntPtr used in my C# program was not being retained when a seperate thread (IE the dataevent) called it. When I stepped through the data event portion it didn't fail until i called the TurnImagerOff() portion. It was a easy fix in that all i had to do was change both my serial port and my IntPtr into static Members. I tried that in the VB.net code...but evidently I'm not smart enough to figure that out. Oh well today is another day, and atleast 50% of my code works.

So for those of you who have a null reference error and can't find it any where. And the Stack Trace doesn't give you a line number, check anything that is running on another thread that is making a call to any members that are pointers. (Or reflected as a pointer). Check data events, Thread Pools, Background workers, Timers, delegates, etc. I hope that my follies will help someone else.

share|improve this answer
add comment

Your Answer


