amp
amp

Reputation: 12352

NullReferenceException on unmanaged c++ code

I have a C++ DLL that I need to use in may c# project.

Here is the important part of my code:

public static class MTSCRA_API
{
    [UnmanagedFunctionPointer(CallingConvention.StdCall)]
    public delegate void DataReceiveDelegate([MarshalAsAttribute(UnmanagedType.LPStr)]String x);

    //More methods....

    [DllImport("MTSCRA.dll", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Auto, SetLastError = true)]
    public static extern void OnDeviceConnectionStateChanged(IntPtr lpFuncNotify);

}

Where I use it:

public void Open()
        {
            if (!MTSCRA_API.IsDeviceConnected())
            {
                UInt32 result = MTSCRA_API.OpenDevice("");
                if (result == 0)
                {
                    MTSCRA_API.OnDataReceived(
                        Marshal.GetFunctionPointerForDelegate(
                        new Kiosk.Hardware.CardReaderMagTek.MTSCRA_API.DataReceiveDelegate(CardReaderMagTek_OnCardDataReceived)));
                }
            }
    }

    Mutex mutex = new Mutex();
    void CardReaderMagTek_OnCardDataReceived(String info)
    {
        try
        {
             //Do stuff
        }
        catch(Exception ex)
        {

        }
        finally
        {
            mutex.ReleaseMutex();
        }
        MTSCRA_API.ClearCardData();
        info = null;

    }

Each time I swipe a card in a device, the CardReaderMagTek_OnCardDataReceived() event is called.

The Open() method is executed and the event CardReaderMagTek_OnCardDataReceived() is called but only 9 times. A the 10º the code crash with a NullReferenceException without entering in the event and I don't have access to the callstack...

Anyone knows what could be the problem?

Upvotes: 2

Views: 505

Answers (1)

David Heffernan
David Heffernan

Reputation: 613412

MTSCRA_API.OnDataReceived(
    Marshal.GetFunctionPointerForDelegate(
    new Kiosk.Hardware.CardReaderMagTek.MTSCRA_API.DataReceiveDelegate(
        CardReaderMagTek_OnCardDataReceived)
    )
);

You are not keeping your delegate alive. You create an instance of DataReceiveDelegate and pass it to GetFunctionPointerForDelegate. But after GetFunctionPointerForDelegate returns, there's no reason for the delegate to stay alive. At some point it will be collected.

Hold the delegate in a managed variable for as long as the unmanaged function needs to be able to call it.

Upvotes: 2

Related Questions