December 04, 2013 extern(C) delegate | ||||
---|---|---|---|---|
| ||||
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? |
December 04, 2013 Re: extern(C) delegate | ||||
---|---|---|---|---|
| ||||
Posted in reply to Mariusz `shd` Gliwiński | 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? |
Copyright © 1999-2021 by the D Language Foundation