2012-07-05 45 views
4

我正在研究需要調用C++ dll的C#gui應用程序。似乎所有的通話都在工作,除了特別的通話。從C++頭文件中的函數和回調簽名是這樣的:C++中的VC++ __stdcall回調函數#

typedef void (__stdcall *LPFNDLL_RECEIVE_CALLBACK)(CANMsg*); 

USBCANPLUS_API 
CAN_STATUS __stdcall canplus_setReceiveCallBack(
    CANHANDLE handle, 
    LPFNDLL_RECEIVE_CALLBACK cbfn 
); 

基於讀數我已經安裝和內部類包裹所述呼叫作爲這樣:

[DllImport("USBCanPlusDllF.dll")] 
public static extern int canplus_setReceiveCallBack(int handle, CallbackDelegate callback); 

[UnmanagedFunctionPointerAttribute(CallingConvention.StdCall)] 
public delegate void CallbackDelegate(ref CANMsg msg); 

並用作:

private static void callback(ref EASYSYNC.CANMsg msg) 
    { 
     Debug.Print(msg.id + ":" + msg.timestamp + ":" + msg.flags + ":" + msg.len + ":" + msg.data); 
    } 

    static EASYSYNC.CallbackDelegate del = new EASYSYNC.CallbackDelegate(callback); 

    private void button1_Click(object sender, EventArgs e) 
    { 
     int handle = EASYSYNC.canplus_Open(IntPtr.Zero, "1000", IntPtr.Zero, IntPtr.Zero, 0); 

     if(handle > 0) 
     { 
      int result = EASYSYNC.canplus_setReceiveCallBack(handle, del); 
     } 
    } 

我知道在C#中處理C++回調是棘手的,並已閱讀了一些主題,因此我有上面的代碼。我的問題是我的代碼命中int結果= ....行整個程序出去吃午餐,表明我可能仍然在處理回調做錯了。任何人都可以建議嗎?

+1

這是一個錯誤?我希望在'int result ='行末尾看到'(handle,del)'而不是'(handle,callback)'。 – dialer 2012-07-05 13:22:21

+2

*永遠不要*在回調中使用消息框,請改用Debug.Print()。當垃圾收集器破壞委託時,你的代碼也會彈出,你需要將它保存在一個靜態變量中。 – 2012-07-05 13:25:03

+0

確實是一個錯字。我會在原文中更正。 – 2012-07-05 13:26:28

回答

0

我對此有點不確定,但是您已經將委託的調用約定指定爲StdCall(它必須是因爲C/C++代碼這麼說),但是您沒有爲canplus_setReceiveCallBack()dllimport函數聲明,它是當你做了以下工作:

[DllImport("USBCanPlusDllF.dll", CallingConvention=CallingConvention.StdCall)] 
public static extern int canplus_setReceiveCallBack(int handle, CallbackDelegate callback); 

正如我所說的,我不清楚,但是這可能是問題。