On Thursday, 3 April 2014 at 18:13:31 UTC, Adam D. Ruppe wrote:
On Thursday, 3 April 2014 at 17:59:33 UTC, Jeroen Bollen wrote:
How do I pass a delegate to an external C function taking a function pointer?


You can't do it directly in general, unless you can modify the C function, then you can hack around it, but a delegate and a regular function pointer are pretty different animals.

But perhaps you can magic hack it. Observe:

// a C function that needs a plain function
extern(C) void test(void function() f) {
        // pretend this impl is in C
        f();
}

// just create a random delegate
void delegate() foo(int a) {
        return { import std.stdio; writeln(a); };
}

// what we want to work
void main() {
        auto dg = foo(10);
        dg(); // works

        //test(dg); // won't work
        test(bindDelegate(dg)); // we want this
}

// transform delegate into pointer..
import std.traits;
auto bindDelegate(T, string file = __FILE__, size_t line = __LINE__)(T t) if(isDelegate!T) {
        static T dg;

        dg = t;

        extern(C)
        static ReturnType!T func(ParameterTypeTuple!T args) {
                return dg(args);
        }

        return &func;
}




What bindDelegate does is create a special static variable and function for that specific call. It is as if we wrote a separate function and global to hold it.

The __FILE__, __LINE__ things are a filthy hack to make it instantitate a separate variable+function pair for different lines so the global variable holding the delegate won't be so easily overwritten.

Thanks.

Reply via email to