www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - How to pass delegates to C functions?

reply "Jeroen Bollen" <jbinero gmail.com> writes:
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
Apr 03 2014
next sibling parent reply Justin Whear <justin economicmodeling.com> writes:
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?
Apr 03 2014
parent "Jeroen Bollen" <jbinero gmail.com> writes:
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.
Apr 03 2014
prev sibling next sibling parent reply "Adam D. Ruppe" <destructionator gmail.com> writes:
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.
Apr 03 2014
parent "Jeroen Bollen" <jbinero gmail.com> writes:
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.
Apr 03 2014
prev sibling parent reply "Mengu" <mengukagan gmail.com> writes:
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!
Apr 03 2014
parent "Jeroen Bollen" <jbinero gmail.com> writes:
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
Apr 03 2014