1

Say I am interfacing to C.

Here is an wrapping function to the interface.

@property extern(C) void onEvent(void function(InterfaceStruct*, int, int, int) nothrow callback)
{
        interfaceSetCallback(handle, callback);
}

All good.

wrapper.onEvent = function void  (InterfaceStruct*, int x, int y, int z) nothrow
{
        if (x == 11) doSomething();
};

Uh oh:

Error: function foo.bar.onEvent (void function(InterfaceStruct*, int, int, int) nothrow callback) is not callable using argument types (void function(InterfaceStruct* _param_0, int x, int y, int z) nothrow @nogc @safe)

So, it wants me to have the function literal being extern(C). So how can I do that? I can't find any way to do so.

hpm
  • 1,202
  • 13
  • 34

1 Answers1

3

Instead of providing the whole function definition you can simply assign onEvent using

wrapper.onEvent = (a, x, y, z)
{
    if (x == 11) doSomething();
};

D will automatically assign it the correct type.

Also your code should actually give you a syntax error because extern(C) is actually not allowed when using it for a function pointer definition.

You could alternatively define an alias for the function pointer type and cast the assignment to it like this:

alias EventCallback = extern(C) void function(InterfaceStruct*, int, int, int) nothrow;

@property extern(C) void onEvent(EventCallback callback)
{
        interfaceSetCallback(handle, callback);
}

// ...

wrapper.onEvent = cast(EventCallback) function void(InterfaceStruct*, int x, int y, int z) nothrow
{
        if (x == 11) doSomething();
};
WebFreak001
  • 2,415
  • 1
  • 15
  • 24
  • Hey, thanks! I couldn't find too much online about function pointers or literals. Also, thanks for the second option you gave. I already knew about that one (after looking at some other code), but I don't use casts as much as possible. Luckily, for now, I don't have to. – hpm Apr 03 '16 at 10:43