How to pass delegates to C functions?

Jeroen Bollen jbinero at gmail.com
Thu Apr 3 11:28:36 PDT 2014


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.


More information about the Digitalmars-d-learn mailing list