c# - FunctionPointer/IntPtr and delegate conver...

While with some occasions, you have to translate some c# construct to that equivalent of native representation. this is common, an example of such conversion is when you try to convert a delegate (function/method) to a IntPtr which will be accepted by a pinovke calls.

normally you have two ways of doing such.

1. the Marshal.GetFunctionPointerForDelegate. 

Let's see a code snippet. We will pass one function pionter by the address of one method to the WNDCLASSEX class. 

the code snippet is as follow. 

WNDCLASSEX wcx = new WNDCLASSEX();

 

            wcx.cbSize = Marshal.SizeOf(wcx);

            wcx.style = (int) (ClassStyles.VerticalRedraw | ClassStyles.HorizontalRedraw);

 

            unsafe

            {

                //IntPtr address = MainWndProc; -- this is not necessary to put inside a Unsafe context

                IntPtr address2 = Marshal.GetFunctionPointerForDelegate((Delegate) (WndProc) MainWndProc);

                wcx.lpfnWndProc = address2;

            }

A special note on the the unsafe block, it is not necessary to have the unsafe block wrapping the code. 

and the MainWndProc is something like this:

        static IntPtr MainWndProc(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam)

        {

            IntPtr hdc;

            PAINTSTRUCT ps;

            RECT rect;

            //switch ((WM) message)

            //{

            //    WinAPI.BeginPaint(hWnd, out ps);

            //    break;

            //}

            switch ((WM)msg)

            {

                case WM.PAINT:

                    hdc = WinAPI.BeginPaint(hWnd, out ps);

                    WinAPI.GetClientRect(hWnd, out rect);

                    WinAPI.DrawText(hdc, "Hello, Windows 98!", -1, ref rect, Win32_DT_Constant.DT_SINGLELINE | Win32_DT_Constant.DT_CENTER | Win32_DT_Constant.DT_VCENTER);

                    WinAPI.EndPaint(hWnd, ref ps);

                    return IntPtr.Zero;

                    break;

                case WM.DESTROY:

                    WinAPI.PostQuitMessage(0);

                    return IntPtr.Zero;

                    break;

            }

 

            return WinAPI.DefWindowProc(hWnd, (WM)msg, wParam, lParam);

        }

the definition of the Delegate WndProc is something like this:

public delegate IntPtr WndProc(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam);

2. Delegate.Method.MethodHandle.GetFunctionPointer();

Another way, which is less ideal is you can use the Delegate's method property and then you can further get to the MethodHandle, and the last call GetFunctionPointer().

E.g is as follow. 

            wndClass.lpfnWndProc = ((WndProc)((hWnd, message, wParam, lParam) =>

            {

                IntPtr hdc;

                PAINTSTRUCT ps;

                RECT rect;

                //switch ((WM) message)

                //{

                //    WinAPI.BeginPaint(hWnd, out ps);

                //    break;

                //}

                switch ((WM)message)

                {

                    case WM.PAINT:

                        hdc = WinAPI.BeginPaint(hWnd, out ps);

                        WinAPI.GetClientRect(hWnd, out rect);

                        WinAPI.DrawText(hdc, "Hello, Windows 98!", -1, ref rect, Win32_DT_Constant.DT_SINGLELINE | Win32_DT_Constant.DT_CENTER | Win32_DT_Constant.DT_VCENTER);

                        WinAPI.EndPaint(hWnd, ref ps);

                        return IntPtr.Zero;

                        break;

                    case WM.DESTROY:

                        WinAPI.PostQuitMessage(0);

                        return IntPtr.Zero;

                        break;

                }

 

                return WinAPI.DefWindowProc(hWnd, (WM)message, wParam, lParam);

            }

            )).Method.MethodHandle.GetFunctionPointer();


转载于:https://my.oschina.net/u/854138/blog/140113

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值