Thread overview
Using delegates in callbacks for extern(C) functions
Feb 24, 2012
simendsjo
Feb 25, 2012
Timon Gehr
Feb 25, 2012
simendsjo
Feb 28, 2012
Ali Çehreli
Feb 28, 2012
Jonathan M Davis
February 24, 2012
I have a C function taking a callback function as a parameter. My thought was to wrap this up using a template, but I cannot get it to work:

extern(C) alias void function() Callback;

template Wrap(alias dg)
{
    extern(C) void Wrap()
    {
        dg();
    }
}

void main()
{
    Callback cb = &Wrap!( () {} );
}

Error: cannot implicitly convert expression (&Wrap) of type void delegate() pure nothrow @safe to extern (C) void function()
February 25, 2012
On 02/24/2012 07:22 PM, simendsjo wrote:
> I have a C function taking a callback function as a parameter. My
> thought was to wrap this up using a template, but I cannot get it to work:
>
> extern(C) alias void function() Callback;
>
> template Wrap(alias dg)
> {
> extern(C) void Wrap()
> {
> dg();
> }
> }
>
> void main()
> {
> Callback cb = &Wrap!( () {} );
> }
>
> Error: cannot implicitly convert expression (&Wrap) of type void
> delegate() pure nothrow @safe to extern (C) void function()

This is a bug. '() {}' should be inferred as void function()pure nothrow @safe. Workaround: The code compiles if you use function() {} instead. I don't know if a bug report exists already.
February 25, 2012
On Sat, 25 Feb 2012 17:12:50 +0100, Timon Gehr <timon.gehr@gmx.ch> wrote:

> On 02/24/2012 07:22 PM, simendsjo wrote:
>> I have a C function taking a callback function as a parameter. My
>> thought was to wrap this up using a template, but I cannot get it to work:
>>
>> extern(C) alias void function() Callback;
>>
>> template Wrap(alias dg)
>> {
>> extern(C) void Wrap()
>> {
>> dg();
>> }
>> }
>>
>> void main()
>> {
>> Callback cb = &Wrap!( () {} );
>> }
>>
>> Error: cannot implicitly convert expression (&Wrap) of type void
>> delegate() pure nothrow @safe to extern (C) void function()
>
> This is a bug. '() {}' should be inferred as void function()pure nothrow @safe. Workaround: The code compiles if you use function() {} instead. I don't know if a bug report exists already.

Thanks. http://d.puremagic.com/issues/show_bug.cgi?id=7585
February 28, 2012
On 02/25/2012 08:12 AM, Timon Gehr wrote:
> On 02/24/2012 07:22 PM, simendsjo wrote:
>> I have a C function taking a callback function as a parameter. My
>> thought was to wrap this up using a template, but I cannot get it to
>> work:
>>
>> extern(C) alias void function() Callback;
>>
>> template Wrap(alias dg)
>> {
>> extern(C) void Wrap()
>> {
>> dg();
>> }
>> }
>>
>> void main()
>> {
>> Callback cb = &Wrap!( () {} );
>> }
>>
>> Error: cannot implicitly convert expression (&Wrap) of type void
>> delegate() pure nothrow @safe to extern (C) void function()
>
> This is a bug. '() {}' should be inferred as void function()pure nothrow
> @safe.

Not according to the spec: "If the keywords function or delegate are omitted, it defaults to being a delegate"

  http://dlang.org/expression.html#FunctionLiteral

> Workaround: The code compiles if you use function() {} instead.

If I read the spec correctly, one must use the 'function' keyword.

Ali

February 28, 2012
On Monday, February 27, 2012 16:42:06 Ali Çehreli wrote:
> On 02/25/2012 08:12 AM, Timon Gehr wrote:
> > On 02/24/2012 07:22 PM, simendsjo wrote:
> >> I have a C function taking a callback function as a parameter. My thought was to wrap this up using a template, but I cannot get it to work:
> >> 
> >> extern(C) alias void function() Callback;
> >> 
> >> template Wrap(alias dg)
> >> {
> >> extern(C) void Wrap()
> >> {
> >> dg();
> >> }
> >> }
> >> 
> >> void main()
> >> {
> >> Callback cb = &Wrap!( () {} );
> >> }
> >> 
> >> Error: cannot implicitly convert expression (&Wrap) of type void
> >> delegate() pure nothrow @safe to extern (C) void function()
> > 
> > This is a bug. '() {}' should be inferred as void function()pure nothrow
> > @safe.
> 
> Not according to the spec: "If the keywords function or delegate are omitted, it defaults to being a delegate"
> 
> http://dlang.org/expression.html#FunctionLiteral
> 
> > Workaround: The code compiles if you use function() {} instead.
> 
> If I read the spec correctly, one must use the 'function' keyword.

TDPL says that it's inferred, and I believe that work was recently done in improving the compiler's ability to infer it. So, in this case, the spec is almost certainly wrong.

- Jonathan M Davis