Delegates and C function pointers

Nicolas Sicard via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Sat Nov 8 09:49:22 PST 2014


On Saturday, 8 November 2014 at 16:01:09 UTC, anonymous wrote:
> On Saturday, 8 November 2014 at 12:23:45 UTC, Nicolas Sicard
> wrote:
>> I would like to register a D delegate to a C API that takes a
>> function pointer as a callback and a void* pointer to pass data
>> to this callback.
>>
>> My solution is in http://dpaste.dzfl.pl/7d9b504b4b965.
>>
>> Is this code correct? Is there something simpler or already in
>> Phobos that I have overlooked?
>>
>> Thanks
>> -- Nicolas
>
> I think it's a little more complicated than it needs to be.
> Instead of going delegate->DelegateData*->delegate you can pass 
> a
> pointer to the delegate:
>
> void doSomethingFromD(void delegate() dg)
> {
>      static extern(C) void adapter(void* ptr)
>      {
>          auto dg = *cast(void delegate()*)ptr;
>          dg();
>      }
>
>      dosomething(&adapter, &dg);
> }
>
> &dg is fine if dosomething calls the callback before
> doSomethingFromD returns.
>
> If the callback is stored and called later on, you have to put
> the delegate somewhere more lasting. And you have to make sure
> that the GC doesn't collect it in the meantime. In your code
> you're new-ing, but you don't keep the reference around in
> D-land. The GC would happily collect the delegate then, because
> it doesn't look in C-land for references.
>
> For example, you could add all callbacks to a module level 
> array:
>
> void delegate()[] activeCallbacks;
> void doSomethingFromD(void delegate() dg)
> {
>      static extern(C) void adapter(void* ptr)
>      {
>          auto dg = *cast(void delegate()*)ptr;
>          dg();
>      }
>
>      activeCallbacks ~= dg;
>      dosomething(&adapter, &activeCallbacks[$ - 1]);
> }
>
> Then when everything's done and you know that the callbacks are
> not needed anymore, empty activeCallbacks so that the GC can
> collect them.
>
> Essentially, you're back to manual management, and have to think
> about the life times of the callbacks.

Thanks for the advice about the GC managed references! I'll have
a look at it.

-- Nicolas


More information about the Digitalmars-d-learn mailing list