How do I pass a delegate to an external C function taking a function pointer, in D?
Let me cross post what I said on the newsgroup:
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 is implemented 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
instantiate a separate variable+function pair for different
lines so the global variable holding the delegate won't be so
easily overwritten.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With