| |
| Posted by Vladimir Panteleev in reply to Marcone | PermalinkReply |
|
Vladimir Panteleev
Posted in reply to Marcone
| On Thursday, 19 November 2020 at 04:23:13 UTC, Marcone wrote:
> // Function threadingw()
> void threadingw(HWND hwn, void delegate() fun) nothrow {
> try {
> // Function _fun()
> extern(Windows)
> uint _fun(void * arg){
> (*(cast(void delegate()*) arg))(); // Do not show "Hello World!" :(
> return 0;
> }
> CreateThread(null, 0, &_fun, &fun, 0, null);
> } catch(Throwable){}
> }
>
> void main(){
> null.threadingw({writeln("Hello World!");});
>
> }
A delegate is a "fat" pointer (function pointer + context), so it can't fit in a void*.
You could do something like the following to "uncurry" the delegate and extract its context to a void* and a regular function, which can then combine the void* given to it later to call the original delegate:
import std.traits;
auto uncurryDelegate(alias anchor, alias target)()
{
alias Args = Parameters!target;
alias R = ReturnType!target;
alias ContextPtr = void*;
alias Dg = typeof(&target);
union Delegate
{
Dg dg;
struct
{
void* ptr;
void* funcptr;
}
}
auto dg = Delegate(&target);
__gshared void* funcptr; // Will always be the same for this instantiation
funcptr = (&target).funcptr;
static struct Result
{
R function(ContextPtr ptr, Args args) fun;
ContextPtr context;
}
static R fun(ContextPtr ptr, Args args)
{
Delegate dg;
dg.funcptr = funcptr;
dg.ptr = ptr;
return dg.dg(args);
}
return Result(&fun, dg.ptr);
}
auto uncurryDelegate(alias target)()
{
return uncurryDelegate!(target, target);
}
unittest
{
int fun(int i)
{
return i + 1;
}
auto r = uncurryDelegate!fun;
assert(r.fun(r.context, 2) == 3);
}
unittest
{
struct S
{
int i;
int fun(int j)
{
return i + j;
}
auto funUncurried() { return uncurryDelegate!(i, fun); }
}
auto s = S(2);
auto r = s.funUncurried();
assert(r.fun(r.context, 3) == 5);
}
Sadly you can't write `static immutable void* funcptr = (&target).funcptr;`, because the compiler tries to evaluate &target first.
Alternatively you could do this (not recommended): https://stackoverflow.com/a/8656294/21501
|