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" <alienballa...@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?

Reply via email to