2011-09-06 59 views
3

我已經被要求在我的項目中整合webcam ZoneTrigger。該網站提供的SDK也是C++的示例。我已經能夠獲得少量功能。我被卡住的地方是一個回調完成的功能。 代碼樣本C++的回調函數在C#中的非託管c + + DLL ... WINAPI和指針

ZT_SetCallbackProc(ZoneTriggerCallbackProc); 

//在頭文件

typedef int (WINAPI *f_ZT_SetCallbackProc) (void *proc); 
/* 
Sets up the callback function for your application. 
The proc should be declared like this: 

int WINAPI ZoneTriggerCallbackProc(int MessageType, ZT_TRIG_STRUCT *trigInfo); 

MessageType may be one of the following: 
0: Zone Trigger sends a trig. The trigInfo contains data about the hot spots that generated the trig. 
1: Zone Trigger has started and is notifying us that it is ready. This only occurs when Zone Trigger starts after the interface DLL is loaded. 
2: Zone Trigger is shutting down. You application may need to know this. If Zone Trigger is started again, your application will get message 1. 
3: Zone Trigger's Hot spot scheme has changed (a Hot Spot was added or deleted) 
*/ 

我的C#代碼:

[DllImport("ZTcom.dll")] 
    private static extern IntPtr ZT_SetCallbackProc(int ZoneTriggerCallbackProc); 

private unsafe int ZoneTriggerCallbackProc(int MessageType, ref ZT_TRIG_STRUCT trigInfo) 
    { 
     switch (MessageType) 
     { 

      case 0:  //Trig from a Zone Trigger hot spot 
       // string s1 = new string(trigInfo.SpotName); 
       MessageBox.Show("Got a trig from spot" + trigInfo.SpotIndex.ToString()+ s1); 
       break; 

      case 1:  //Zone Trigger has started and is notifying us that it is ready 
       MessageBox.Show("Zone Trigger issued a ready notification.\r\n"); 
       break; 

      case 2:  //Zone Trigger is shutting down 
       MessageBox.Show("Zone Trigger has left the building.\r\n"); 
       break; 

      case 3:  //Hot spot scheme updated, you might want yo re-enumerate the hot spots 
       MessageBox.Show("Zone Trigger's hot spots have been updated.\r\n"); 
       break; 


     } 
     return 0; 
    } 

到目前爲止,我已經到了......但我不瞭解如何調用ZT_SetCallbackProc函數?

IntPtr tg = IntPtr.Zero; 
      tg = ZT_SetCallbackProc(ZoneTriggerCallbackProc); 

這給出錯誤,ZoneTriggerCallbackProc是一個方法組。 PLZ幫助...提前感謝。

+0

我想你需要聲明一個委託,請參見[MSDN](http://msdn.microsoft.com/en-us/library/aa288468/(v = VS.71 \).aspx#pinvoke_registeringcallback)和你的函數可能也需要'靜態'。 – user786653

回答

4

丹尼爾的answer具有簡單快捷的路線。如果您不想遇到問題(因爲委託可能由GC收集導致AccessViolationException),您將需要執行以下操作。

從丹尼爾(的完整性)的類型/ PInvoke的聲明:

// int WINAPI ZoneTriggerCallbackProc(int MessageType, ZT_TRIG_STRUCT *trigInfo); 
delegate int ZoneTriggerCallbackProc(int messageType, ref ZT_TRIG_STRUCT trigInfo); 
[DllImport("ZTcom.dll")] 
private static extern IntPtr ZT_SetCallbackProc(ZoneTriggerCallbackProc callbackProc); 

在你的包裝類,而回調設置保存對委託的引用,使GC不會收集委託。

public class ZoneTrigger : CriticalFinalizerObject 
{ 
    private ZoneTriggerCallbackProc _zoneTriggerCallback; 
    private IntPtr _zoneTriggerCallbackCookie; 

    public ZoneTrigger() 
    { 
    _zoneTriggerCallback = ZoneTriggerCallback; 
    // Why not just do it here? 
    _zoneTriggerCallbackCookie = NativeMethods.ZT_SetCallbackProc(_zoneTriggerCallback); 
    if (_zoneTriggerCallbackCookie == IntPtr.Zero) 
     throw new Exception("Failed to set callback"); 
    } 

    private unsafe int ZoneTriggerCallback(int MessageType, ref ZT_TRIG_STRUCT trigInfo) 
    { 
    // ... 
    } 

    ~ZoneTrigger() 
    { 
    var oldCookie = Interlocked.Exchange(ref _zoneTriggerCallback, IntPtr.Zero); 
    if (oldCookie != IntPtr.Zero) 
     ZT_ClearCallbackProc(oldCookie); 
    } 
} 

注:請接受丹尼爾的回答,這更多的是除了它的。

+0

非常感謝你...這工作....我接受丹尼爾的答案,但我仍然b失去,如果你還沒有給出上述解釋.. 。 非常感謝你..... – Anu

0

調用該函數如下....

ZT_TRIG_STRUCT triginfo = new ZT_TRIG_STRUCT(); 
IntPtr tg = IntPtr.Zero; 
     tg = ZT_SetCallbackProc(ZoneTriggerCallbackProc(0,triginfo)); 
2

回調函數是這樣一種方法。所以你需要傳遞一個方法。在C#中你得到的是通過定義一個委託:

// int WINAPI ZoneTriggerCallbackProc(int MessageType, ZT_TRIG_STRUCT *trigInfo); 
delegate int ZoneTriggerCallbackProc(int messageType, ref ZT_TRIG_STRUCT trigInfo); 

[DllImport("ZTcom.dll")] 
private static extern IntPtr ZT_SetCallbackProc(ZoneTriggerCallbackProc callbackProc); 
+0

非常感謝你....這工作得很好... – Anu