On 05/20/2018 06:48 PM, IntegratedDimensions wrote:
alias callback = extern(C) int function(const(void) a, void *b, uint c, void* context);

(I'm assuming that `a` is supposed to be a `const(void)*`.)

Where context acts as this.

I would like to assign a D method to this callback.

class
{
    callback c;
   /*extern(C) static*/ int foo(const(void) a, void *b, uint c, void* context);

    this() { c = cast(callback)&foo; }
}

Unless I'm misunderstanding it, the spec seems to say that the `this` pointer is passed as if it was an additional parameter past the last one [1].

But that doesn't seem to be true in the implementation. At least on Linux x86-64, `this` seems to be a hidden first parameter. So when a method is called as a `callback`, `a` becomes `this`, `b` becomes the first explicit parameter, `c` the second, and `context` the third. So this works:

----
import std.stdio;

alias Callback = extern(C) int function(const(void)* a, void* b, uint c,
    void* context);

class C
{
    int field = 43;
    extern(C) int foo(void* b, uint c, C this_)
    {
        const(void)* a = cast(void*) this;
        writeln(a, " ", b, " ", c, " ", this_.field);
        return 0;
    }
}

void main()
{
    void* a = new int;
    void* b = new int;
    uint c = 42;
    auto obj = new C;
    Callback cb = cast(Callback) (&obj.foo).funcptr;
    cb(a, b, c, cast(void*) obj);
    writeln(a, " ", b, " ", c, " ", obj.field);
        /* For comparison. Should print the same. */
}
----

This is all very hacky, of course. And I don't really know what I'm doing there. So obviously, I don't recommend doing this.

But other than hacking it like that, I don't think you can pass a method as a `callback` directly.


[1] https://dlang.org/spec/abi.html#parameters

Reply via email to