This is from one of the C# books. What I don't understand is that for this to be a callback, shouldn't the EnumWindow call to PrintWindow be made from user32.dll. Maybe, I am not understanding delegates or callback properly. Please help me to understand.
Callbacks from Unmanaged Code
The P/Invoke layer does its best to present a natural programming model on both sides of the boundary, mapping between relevant constructs where possible. Since C# can not only call out to C functions but also can be called back from the C functions (via function pointers), the P/Invoke layer maps unmanaged function pointers into the nearest equivalent in C#, which is delegates.
As an example, you can enumerate all top-level window handles with this method in User32.dll:
BOOL EnumWindows (WNDENUMPROC lpEnumFunc, LPARAM lParam);
WNDENUMPROC is a callback that gets fired with the handle of each window in sequence (or until the callback returns false). Here is its definition:
BOOL CALLBACK EnumWindowsProc (HWND hwnd, LPARAM lParam);
To use this, we declare a delegate with a matching signature, and then pass a delegate instance to the external method:
using System;
using System.Runtime.InteropServices;
class CallbackFun
{
delegate bool EnumWindowsCallback (IntPtr hWnd, IntPtr lParam);
[DllImport("user32.dll")]
static extern int EnumWindows (EnumWindowsCallback hWnd, IntPtr lParam);
static bool PrintWindow (IntPtr hWnd, IntPtr lParam)
{
Console.WriteLine (hWnd.ToInt64());
return true;
}
static void Main()
{
EnumWindows (PrintWindow, IntPtr.Zero);
}
}