C style callbacks fix for member callbacks

IntegratedDimensions IntegratedDimensions at gmail.com
Mon May 21 01:05:26 UTC 2018


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.


More information about the Digitalmars-d-learn mailing list