On Sunday, 20 May 2018 at 23:05:47 UTC, ag0aep6g wrote:
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

I tried this. Your code crashes in windows dmd x86 x64.

It really shouldn't be hacky. The only difference is the "this" is implicit normally when in this case it is explicit and possibly in a different location than one expects.

Reply via email to