Exception caused by anonymous method

Source: Internet
Author: User
Exception caused by anonymous method

Problem: I recently compiled a low-level keyboard hook, usingC #Production, so we useWin32 API. However, exceptions may occur in the near future due to illegal memory access.

Debugging finds that exceptions cannot be captured.

StaticClassProgram
{
PrivateStaticHooklogHooklog;

/// <Summary>
/// The main entry point for the application.
/// </Summary>
[ Stathread ]
Static Void Main ()
{
Hooklog = New Hooklog ( Form1 . Apppath );
Application . Enablevisualstyles ();
Application . Setcompatibletextrenderingdefault ( False );
Application . Threadexception + = New System. Threading. threadexceptioneventhandler (application_threadexception );
Application . Run (New Form1 ());
}

StaticVoidApplication_threadexception (Object sender, system. Threading. threadexceptioneventargs E)
{

Hooklog. logexceptioninfo (E. Exception );
}
}

 

Exception occurs inApplication. Run (New form1 ())OfCodeLine.

The prompt is:HookprocThe callback function is released. So I understood what was going on.

Where,HookprocIs a declared delegate callback type:

Public Delegate Intptr Hookproc(IntNcode,IntptrWparam,IntptrLparam );

This type is consistentWindowsThe callback Letter of the hook is consistent with the prototype.

Hook installation function:

Public VoidSetup ()

{

If(Handle! =Intptr. Zero)

Return;

Using(ProcessProcess =Process. Getcurrentprocess ())

{

Using(ProcessmoduleModule = process. mainmodule)

{

// Handle = WIN32API. setwindowshookex (windowshooktypes. wh_keyboard_ll,

// New hookproc (processkeyevent), WIN32API. getmodulehandle (module. modulename), // 0 );

Handle =WIN32API. Setwindowshookex (Windowshooktypes. Wh_keyboard_ll,

Kbdhookproc,WIN32API. Getmodulehandle (module. modulename), 0 );

If(Handle! =Intptr. Zero)

WIN32API. Messagebeep (Messagebeeptypes. Iconexclamation );

}

}

}

The code that causes exceptions is highlighted in green. Because anonymous delegation is directly used. That is, the generated object is a temporary object,New hookproc (processkeyevent)This object is not saved. Therefore, for the part of the managed code, the delegate callback object will exist as a temporary variable.

However, by callingWin32 API --- setwindowshookexThe object is passed to the unmanaged code. In this way, a problem occurs. The managed code section recycles the most temporary object of the object because it is found that it is not referenced anywhere in the managed code. The unmanaged code will still call this callback, because it cannot know that the hosted code has released this pointer. This is why an out-of-bounds access exception cannot be captured shortly after running.

Modify the following line of code to be commented out,ProgramIt is normal.

Handle =WIN32API. Setwindowshookex (Windowshooktypes. Wh_keyboard_ll,Kbdhookproc,WIN32API. Getmodulehandle (module. modulename), 0 );

CodeKbdhookprocIs a member variable declared in the class:

/// <Summary>
/// Keyboard hook callback function
/// </Summary>
Private Hookproc Kbdhookproc;
/// <Summary>
/// Constructor
/// </Summary>
Public Lowlevelkeboardhook ()
{
Disposed = False ;
Handle = Intptr . Zero;
Kbdhookproc = New Hookproc (processkeyevent );
}

/// <Summary>
/// Keyboard hook processing function
/// </Summary>
Private Intptr Processkeyevent ( Int Ncode, Intptr Wparam, Intptr Lparam)
{
KBDLLHOOKSTRUCT ? RFS = Marshal . Ptrtostructure (lparam, Typeof ( KBDLLHOOKSTRUCT )) As KBDLLHOOKSTRUCT ?;
If (Keyboardevent! = Null & RFS. hasvalue)
{
Int Tag = wparam. toint32 ();
If (TAG = ( Int )Windowsmessagetypes . Wm_keydown | tag = ( Int ) Windowsmessagetypes . Wm_syskeydown)
Keyboardevent (ncode, RFS. value. vkcode, RFS. value. Flags );
}
Return WIN32API . Callnexthookex (handle, ncode, wparam, lparam );
}

In this way, it does not seem to change much. However, the class member variables remember this callback delegate object, so it will not be recycled by garbage collection.

Therefore, when using anonymous functions, anonymous delegation, and anonymous temporary objects, you must be extremely careful when it comes to unmanaged code.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.