Thread overview
How to pass delegates to C functions?
Apr 03, 2014
Jeroen Bollen
Apr 03, 2014
Justin Whear
Apr 03, 2014
Jeroen Bollen
Apr 03, 2014
Adam D. Ruppe
Apr 03, 2014
Jeroen Bollen
Apr 04, 2014
Mengu
Apr 04, 2014
Jeroen Bollen
April 03, 2014
After being downvoted on stackoverflow for no apperant reason, I figured I'd give it a shot here.

How do I pass a delegate to an external C function taking a function pointer?

If you want some extra rep on StackOverflow you can also answer here: http://stackoverflow.com/questions/22845175/pass-delegates-to-external-c-functions-in-d
April 03, 2014
On Thu, 03 Apr 2014 17:59:30 +0000, Jeroen Bollen wrote:

> After being downvoted on stackoverflow for no apperant reason, I figured I'd give it a shot here.
> 
> How do I pass a delegate to an external C function taking a function pointer?
> 
> If you want some extra rep on StackOverflow you can also answer here: http://stackoverflow.com/questions/22845175/pass-delegates-to-external-
c-functions-in-d

Does the C function use the function pointer (call it), or just pass it around/store it?
April 03, 2014
On Thursday, 3 April 2014 at 18:05:26 UTC, Justin Whear wrote:
> On Thu, 03 Apr 2014 17:59:30 +0000, Jeroen Bollen wrote:
>
>> After being downvoted on stackoverflow for no apperant reason, I figured
>> I'd give it a shot here.
>> 
>> How do I pass a delegate to an external C function taking a function
>> pointer?
>> 
>> If you want some extra rep on StackOverflow you can also answer here:
>> http://stackoverflow.com/questions/22845175/pass-delegates-to-external-
> c-functions-in-d
>
> Does the C function use the function pointer (call it), or just pass it
> around/store it?

It will get called.
April 03, 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.
April 03, 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.
April 04, 2014
On Thursday, 3 April 2014 at 17:59:33 UTC, Jeroen Bollen wrote:
> After being downvoted on stackoverflow for no apperant reason, I figured I'd give it a shot here.
>
> How do I pass a delegate to an external C function taking a function pointer?
>
> If you want some extra rep on StackOverflow you can also answer here: http://stackoverflow.com/questions/22845175/pass-delegates-to-external-c-functions-in-d

OT: you've got another upvote!
April 04, 2014
On Friday, 4 April 2014 at 05:20:42 UTC, Mengu wrote:
> On Thursday, 3 April 2014 at 17:59:33 UTC, Jeroen Bollen wrote:
>> After being downvoted on stackoverflow for no apperant reason, I figured I'd give it a shot here.
>>
>> How do I pass a delegate to an external C function taking a function pointer?
>>
>> If you want some extra rep on StackOverflow you can also answer here: http://stackoverflow.com/questions/22845175/pass-delegates-to-external-c-functions-in-d
>
> OT: you've got another upvote!

Ever since I posted it here it started climbing back up the ladder. Doesn't really matter now anyways, I got my answer. :P