Thread overview | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|
|
June 25, 2016 Does D has any support for thunks? | ||||
---|---|---|---|---|
| ||||
Hi everyone, I have some issue with win32 function SetWindowsHookEx. For this specific funtion there is no possibility to pass extra data (pointer to a class instance to be called) to the callback function. The general solution seems to use thunks. I found s.th. for c++: http://www.codeproject.com/Articles/16785/Thunking-in-Win-Simplifying-Callbacks-to-Non-sta Does D/Phobos has any support for thunks? Kind regards André |
June 25, 2016 Re: Does D has any support for thunks? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andre Pany | On Saturday, 25 June 2016 at 13:44:48 UTC, Andre Pany wrote:
> Does D/Phobos has any support for thunks?
It isn't included in the stdlib, but you can use the same C++ they describe in the link in D.
|
June 25, 2016 Re: Does D has any support for thunks? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andre Pany | On Saturday, 25 June 2016 at 13:44:48 UTC, Andre Pany wrote: > Hi everyone, > > I have some issue with win32 function SetWindowsHookEx. For this specific funtion there is no possibility to pass extra data (pointer to a class instance to be called) to the callback function. > > The general solution seems to use thunks. I found s.th. for c++: > http://www.codeproject.com/Articles/16785/Thunking-in-Win-Simplifying-Callbacks-to-Non-sta > > Does D/Phobos has any support for thunks? > > Kind regards > André This will only work on X86: version(X86) struct FunctionPtr(TDelegate) if (is(TDelegate == delegate)) { import std.traits; alias TResult = ReturnType!TDelegate; alias TParameters = Parameters!TDelegate; private struct ThunkCode { align(1): ubyte mov_eax; void* this_ptr; ubyte mov_ecx; void* func_ptr; ubyte mov_edx; void* cb_ptr; ushort jmp_edx; } this(TDelegate method) { this = method; } auto ref opAssign(TDelegate method) { extern(Windows) TResult callback(TParameters parameters) { TDelegate dg = void; asm { mov [dg], EAX; mov [dg + 4], ECX; } return dg(parameters); } if (auto thunk = cast(ThunkCode*)VirtualAlloc(null, ThunkCode.sizeof, MEM_COMMIT, PAGE_EXECUTE_READWRITE)) { with (thunk) { mov_eax = 0xB8; this_ptr = method.ptr; mov_ecx = 0xB9; func_ptr = method.funcptr; mov_edx = 0xBA; cb_ptr = &callback; jmp_edx = 0xE2FF; } FlushInstructionCache(GetCurrentProcess(), thunk, ThunkCode.sizeof); ptr = cast(typeof(ptr))thunk; } else { assert(false); } return this; } ~this() { if (ptr) { VirtualFree(ptr, ThunkCode.sizeof, MEM_DECOMMIT); ptr = null; } } extern(Windows) TResult function(TParameters) nothrow ptr; alias ptr this; } alias HookProc = FunctionPtr!(LRESULT delegate(int, WPARAM, LPARAM)); LRESULT hookProc(int code, WPARAM wparam, LPARAM lparam) { return 0; } HookProc hook = &hookProc; SetWindowsHookEx(WH_KEYBOARD, hook, GetModuleHandle(null), 0); |
June 25, 2016 Re: Does D has any support for thunks? | ||||
---|---|---|---|---|
| ||||
Posted in reply to John | On Saturday, 25 June 2016 at 14:06:51 UTC, John wrote:
> On Saturday, 25 June 2016 at 13:44:48 UTC, Andre Pany wrote:
>> [...]
>
> This will only work on X86:
>
> version(X86)
> struct FunctionPtr(TDelegate) if (is(TDelegate == delegate)) {
>
> [...]
Thanks a lot John, that's fantastic.
Kind regards
André
|
June 25, 2016 Re: Does D has any support for thunks? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andre Pany | On Saturday, 25 June 2016 at 13:44:48 UTC, Andre Pany wrote: > Does D/Phobos has any support for thunks? Made this a while ago: http://stackoverflow.com/a/8656294/21501 |
June 25, 2016 Re: Does D has any support for thunks? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Vladimir Panteleev | On Saturday, 25 June 2016 at 16:05:30 UTC, Vladimir Panteleev wrote:
> On Saturday, 25 June 2016 at 13:44:48 UTC, Andre Pany wrote:
>> Does D/Phobos has any support for thunks?
>
> Made this a while ago:
>
> http://stackoverflow.com/a/8656294/21501
Thanks, I had a look. Unfortunately it doesn't compile for my use case.
SetWindowsHookEx expects an "extern(windows)" and "nothrow" function.
delegate2function does not accept a delegate with
If it is possible to make this coding generic, it would fit into
std.functional.
Kind regards
André
|
June 25, 2016 Re: Does D has any support for thunks? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andre Pany | On Saturday, 25 June 2016 at 17:26:03 UTC, Andre Pany wrote:
> On Saturday, 25 June 2016 at 16:05:30 UTC, Vladimir Panteleev wrote:
>> On Saturday, 25 June 2016 at 13:44:48 UTC, Andre Pany wrote:
>>> Does D/Phobos has any support for thunks?
>>
>> Made this a while ago:
>>
>> http://stackoverflow.com/a/8656294/21501
>
> Thanks, I had a look. Unfortunately it doesn't compile for my use case.
> SetWindowsHookEx expects an "extern(windows)" and "nothrow" function.
> delegate2function does not accept a delegate with
>
> If it is possible to make this coding generic, it would fit into
> std.functional.
>
> Kind regards
> André
... does not accept a delegate with extern(windows).
|
July 02, 2016 Re: Does D has any support for thunks? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andre Pany | On Saturday, 25 June 2016 at 17:52:48 UTC, Andre Pany wrote: > On Saturday, 25 June 2016 at 17:26:03 UTC, Andre Pany wrote: >> On Saturday, 25 June 2016 at 16:05:30 UTC, Vladimir Panteleev wrote: >>> On Saturday, 25 June 2016 at 13:44:48 UTC, Andre Pany wrote: >>>> Does D/Phobos has any support for thunks? >>> >>> Made this a while ago: >>> >>> http://stackoverflow.com/a/8656294/21501 >> >> Thanks, I had a look. Unfortunately it doesn't compile for my use case. >> SetWindowsHookEx expects an "extern(windows)" and "nothrow" function. >> delegate2function does not accept a delegate with >> >> If it is possible to make this coding generic, it would fit into >> std.functional. >> >> Kind regards >> André > > ... does not accept a delegate with extern(windows). You can fix this by a cast: alias callbackType = extern (Windows) uint function(void*); CreateThread(cast(SECURITY_ATTRIBUTES*)null, stackSize, cast(callbackType)delegate2function(c), cast(void*)¶m, (suspended) ? CREATE_SUSPENDED : 0, &Id); But there seems to be a problem as I can only get parameters to pass correctly on dmd x64. |
Copyright © 1999-2021 by the D Language Foundation