2015-09-18 159 views
2

我有一个C++ DLL,我需要在可能C#项目中使用。NullReferenceException对非托管的c + +代码

这里是我的代码的重要组成部分:

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); 

} 

当我使用它:

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; 

    } 

每次我在刷卡设备的存储卡,CardReaderMagTek_OnCardDataReceived()事件被调用。

执行Open()方法并调用事件CardReaderMagTek_OnCardDataReceived(),但仅调用9次。 10º的代码崩溃与NullReferenceException没有进入事件,我没有访问调用堆栈...

任何人都知道可能是什么问题?

回答

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

你没有保持你的代表活着。您创建一个DataReceiveDelegate的实例并将其传递给GetFunctionPointerForDelegate。但GetFunctionPointerForDelegate返回后,代表没有理由继续活着。在某个时候它将被收集。

只要非托管函数需要能够调用它,就将代理保存在托管变量中。

+1

就是这样!我花了太多时间在这...谢谢。 – amp