www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Does D has any support for thunks?

reply Andre Pany <andre s-e-a-p.de> writes:
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é
Jun 25 2016
next sibling parent Adam D. Ruppe <destructionator gmail.com> writes:
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.
Jun 25 2016
prev sibling next sibling parent reply John <johnch_atms hotmail.com> writes:
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);
Jun 25 2016
parent Andre Pany <andre s-e-a-p.de> writes:
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é
Jun 25 2016
prev sibling parent reply Vladimir Panteleev <thecybershadow.lists gmail.com> writes:
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
Jun 25 2016
parent reply Andre Pany <andre s-e-a-p.de> writes:
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é
Jun 25 2016
parent reply Andre Pany <andre s-e-a-p.de> writes:
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).
Jun 25 2016
parent Hiemlick Hiemlicker <HH reign.com> writes:
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*)&param, (suspended) ? CREATE_SUSPENDED : 0, &Id); But there seems to be a problem as I can only get parameters to pass correctly on dmd x64.
Jul 01 2016