digitalmars.D.learn - extern(C) delegate
- "Mariusz `shd` =?UTF-8?B?R2xpd2nFhHNraSI=?= <alienballance gmail.com> (9/9) Dec 04 2013 I'd like to expose my D API to C code.
- =?UTF-8?B?UsOpbXkgTW91w6t6YQ==?= (50/58) Dec 04 2013 I had played with that idea and searched the forums once.
I'd like to expose my D API to C code. For that, i'm going to write templates generate extern(C) definition alongside of D-one. One thing i could do, is to generate D struct that mimics delegate with appropriate arguments. However, i'm curious of another possibility: How do i call extern(C) void test(int delegate(int) dlg = null) from non-extern D code?
Dec 04 2013
I had played with that idea and searched the forums once. I came up with the following proof-of-concept code. in C (c_dg.c) { #include <stdio.h> /// This is how a delegate is implemented (currently). typedef struct Dg { /// The context (class instance or frame or null). void * ctx; /// The function pointer that takes a first extra parameter /// for the context. const char * (*fn) (void * ctx, int i, int j); } Dg; void callDg (Dg dg) { if (dg.fn == NULL) { printf ("it's null.\n"); } else { // This calls the D delegate from C. // One has to pass dg.ctx as first argument. printf ("result: %s\n", dg.fn (dg.ctx, 42, 7)); } } } in D (ddg.d) { import std.stdio; import std.string; import std.conv; extern (C) void callDg (immutable(char)* delegate (int, int)); class X { extern (C) immutable(char)* callMe (int i, int j) { return "%d, %d".format (i, j).toStringz; } } void main () { auto x = new X; callDg (&x.callMe); // Call with a non null delegate. callDg (null); // Case with null. } } I compile and run with: `gcc -c c_dg.c && dmd ddg.d c_dg.o && ./ddg` The program outputs: result: 42, 7 it's null. You should also be aware that the current implementation of delegates are not officially documented and may change in a future version of D. However, from what I understand, it's been implemented like this for quite a while and is unlikely to change any soon. Use at your own risk and have fun! On 12/04/2013 08:27 PM, "Mariusz `shd` GliwiĆski" <alienballance gmail.com>" wrote:I'd like to expose my D API to C code. For that, i'm going to write templates generate extern(C) definition alongside of D-one. One thing i could do, is to generate D struct that mimics delegate with appropriate arguments. However, i'm curious of another possibility: How do i call extern(C) void test(int delegate(int) dlg = null) from non-extern D code?
Dec 04 2013