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








=?UTF-8?B?UsOpbXkgTW91w6t6YQ==?= <remy.moueza gmail.com>