How to pass delegates to C functions?

Adam D. Ruppe destructionator at gmail.com
Thu Apr 3 11:13:30 PDT 2014


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.


More information about the Digitalmars-d-learn mailing list