Re: Function Pointer Not Working

2020-11-19 Thread Marcone via Digitalmars-d-learn

I will wait with this code.
WaitForSingleObject(threading, INFINITE);


Re: Function Pointer Not Working

2020-11-19 Thread Marcone via Digitalmars-d-learn

On Thursday, 19 November 2020 at 15:51:09 UTC, Kagamin wrote:
The delegate is stored on the stack of the calling thread, the 
created thread loads it from there, but the calling thread 
doesn't wait for that and clobbers the stack right away. If you 
were lucky your code would crash.


The thread that I do wait ultil function is finished. Using a 
while with 3 seconds to verify if thread id is in running list, 
and break if not finishing owner thread.


Re: Function Pointer Not Working

2020-11-19 Thread Kagamin via Digitalmars-d-learn
The delegate is stored on the stack of the calling thread, the 
created thread loads it from there, but the calling thread 
doesn't wait for that and clobbers the stack right away. If you 
were lucky your code would crash.


Re: Function Pointer Not Working

2020-11-19 Thread Marcone via Digitalmars-d-learn

Solved replacing this line:

CreateThread(null, 0, &_fun, &fun, 0, null);

to this code:
task!({CreateThread(null, 0, &_fun, &fun, 0, 
null);}).executeInNewThread();


Re: Function Pointer Not Working

2020-11-18 Thread Vladimir Panteleev via Digitalmars-d-learn

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


Function Pointer Not Working

2020-11-18 Thread Marcone via Digitalmars-d-learn

// 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!");});

}