How do I pass a delegate to an external C function taking a function pointer, in D?
可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
回答1:
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.