2015-04-02 31 views
-2

首先,我是完全的,對於任何類型的編程都是100%新的,所以我很抱歉如果這是一個非常明顯的錯誤,但我找不到任何東西。試圖保持代表活着

我想實現我的程序的全局熱鍵,我需要保持這種委託活着防止CallbackOnCollectedDelegate錯誤,但我的代碼給了我兩下生成錯誤:

無效令牌 '(' 類,結構或接口成員聲明

無效標記 ')' 在類,結構或接口成員聲明

public delegate int keyboardHookProc(int code, int wParam, ref keyboardHookStruct lParam); 
    GC.KeepAlive(keyboardHookProc); 

    public struct keyboardHookStruct { 
     public int vkCode; 
     public int scanCode; 
     public int flags; 
     public int time; 
     public int dwExtraInfo; 
    } 

    const int WH_KEYBOARD_LL = 13; 
    const int WM_KEYDOWN = 0x100; 
    const int WM_KEYUP = 0x101; 
    const int WM_SYSKEYDOWN = 0x104; 
    const int WM_SYSKEYUP = 0x105; 

任何幫助表示讚賞,謝謝!

+0

委託是一種類型,你不能在方法體內聲明它。 – Dusan 2015-04-02 12:29:01

+0

令牌錯誤是由於您的代碼組合造成的 – 2015-04-02 12:30:13

+0

您是否可以發佈完整的代碼?在哪裏聲明它? – Rohit 2015-04-02 12:30:35

回答

0

您不能保留代表聲明還活着。也不要爲此使用GC.KeepAlive();儘管它是針對「託管引用到非託管代碼」的情況,但只有在相同方法中設置和清除鉤子時,纔是有用的(有關更多信息,請參閱this link)。

這些鉤子的問題是非託管代碼具有委託的地址,但該參考位於垃圾收集器的雷達下方。所以過了一段時間垃圾收集器開始清理,非託管代碼調用一個現在無效的地址。

如果您的應用程序保持鍵盤在其整個生命週期掛鉤,一個簡單的解決方案是將其分配給一個靜態成員:

static keyboardHookProc myKeyboardDelegate; 

void SetHook() 
{ 
    myKeyboardDelegate = new keyboardHookProc(MyHandler); 
    UnmanagedMethod(myKeyboardDelegate); 
} 

int MyHandler(int code, int wParam, ref keyboardHookStruct lParam) 
{ 
    ... 
} 

有更好的方法,雖然,你可以在一個類包裝這和隱藏從您的應用程序的其餘部分委託。只要確保您保留對您提供給非託管代碼的委託的引用,直到掛鉤被移除。