Running a delegate inside a C function

Denis Martinez via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Sat Jun 7 14:18:38 PDT 2014


On Saturday, 7 June 2014 at 20:37:48 UTC, Chris Cain wrote:
> On Saturday, 7 June 2014 at 20:21:26 UTC, Chris Cain wrote:
>> On Saturday, 7 June 2014 at 20:04:41 UTC, Denis Martinez via 
>> Digitalmars-d-learn wrote:
>>>     int ret = jack_set_process_callback(handle_, f, &dg);
>>
>> &dg here is giving you a pointer to the dg variable sitting on 
>> the stack. The stack is almost certainly getting overwritten 
>> at some point.
>
> I'll add that to fix the problem, you're going to have to write 
> it so that your process_callback function takes either a 
> pointer:
>
>     void process_callback(JackProcessDelegate* dg)
>
> or make it by reference:
>
>     void process_callback(in JackProcessDelegate dg)
>     //... or
>     void process_callback(ref JackProcessDelegate dg)
>
> But do note that the same problem may apply to the person 
> calling it... if they're storing the delegate "structure" on 
> the stack, it might also be clobbered in much the same way.
>
> Take care

Thanks for the answer Chris, you are correct.
I was expecting the closure to work similarly to Clang's blocks, 
which apparently it does not. I guess that delegates pass by 
copy, like structs do.

So far I have tried a variety of solutions.

1. As it is, passing the delegate as "ref" does not work, because 
the compiler does not accept to do the implicit conversion. It is 
the same logic as C++, here in C++11 I would have passed by 
rvalue reference, a thing that does not appear to exist in D.

2. Is it possible to make a delegate to be allocated on the heap ?
I think of a syntax such as:
   client.process_callback = new delegate int(jack_nframes_t 
nframes) {

3. I have coded a workaround for the time being.
The function here copies the delegate into a heap-allocated 
structure, and takes the interior pointer.

   T *copyDelegate(T)(T dg) {
     struct Tmp { T dg; }
     auto x = new Tmp;
     x.dg = dg;
     return &x.dg;
   }

I find this code to be rather inelegant, is there a better 
solution?


More information about the Digitalmars-d-learn mailing list