I have a member callback that I want to use as a C callback.

This is impossible due to the `hidden this` passed as the "first" parameter.

The callback already makes it's last value a user pointer which I use as a "this".

If I make my method static extern(C) then there is no crash and everything works. The problem is that it is now a static function within the class which I want to avoid.

Because there is actually a "this pointer" I can make it a member function and everything works as long as the calling convention is right.

I was initially wrapping the callback in a delegate that made it all work out but I want to avoid that level of indirection since it should not be necessary.

I have tried manually reversing the arguments, using various calling conventions, etc but everything crashes except when I use extern(C) static without modifying the order.

extern(C) static foo(a,b,c,d)

puts the parameters on the stack as d,c,b,a

foo(a,b,c,d)

is d,c,b,a,this (? The ABI does not make it clear what order is pushed on the stack. It uses the terminology "passes" and I assume that the calling convention is C'ish although extern(C) matters).


works

extern(C) static foo(a,b,c,d)

does not work

static foo(d,c,b,a)

So something else is going on

"The last parameter is passed in EAX rather than being pushed on the stack if the following conditions are met:

    It fits in EAX.
    It is not a 3 byte struct.
    It is not a floating point type.
"

Can someone clarify the exact calling convention process for C vs D along with any potential solutions to the above problem(using static is not a solution).

Just to make sure we are on the same page:

class
{
   void extern(C) static foo(a,b,c,mythis);
}

works while

class
{
   void extern(C) foo(a,b,c);
}

fails.

class
{
   void foo(c,b,a);
}

also fails.










Reply via email to