You'll certainly have to make a C++ wrapper. However, a delegate being implemented as a struct containing a context pointer and a function, you can get some degree of interoperability between C++ and D (BUT note that it is an undocumented implementation detail subject to change without notice -- althought it hasn't changed in many years):

/* =========================================================== */
/// ddg.d
import std.stdio;
import std.string;

/// A C++ function that will take a D delegate.
extern (C) void callDg (immutable(char)* delegate (int, int));

/// A dummy class.
class X {
    /// This method can be used as a delegate.
    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);

/* =========================================================== */
/// cpp_dg.cpp
#include <iostream>

using namespace std;

/// A D delegate representation in C++.
struct Dg {
    /// The context pointer.
    void * ctx;

/// The function within the delegate: the first argument is the context pointer.
    const char *(*dg) (void * ctx, int i, int j);

    /// C++ sugar: calling a struct Dg as a function.
    const char * operator ()(int i, int j) {
        return dg (ctx, i, j);

/// Extern C allows D compatibilty.
extern "C" {
    void callDg (Dg dg) {
        /// Call the extern (C) D delegate.
        cout << dg (42, 7) << endl;
/* =========================================================== */
$ g++ -c cpp_dg.cpp
$ dmd ddg.d cpp_dg.o -L-lstdc++
$ ./ddg
42, 7
/* =========================================================== */

According to "
> Class template std::function is a general-purpose polymorphic
> function wrapper. Instances of std::function can store, copy, and
> invoke any Callable target -- functions, lambda expressions, bind
> expressions, or other function objects, as well as pointers to member
> functions and pointers to data members.

Thus the struct Dg in the example above should be compatible with the Botan constructors.

Also, extern (C) delegates are not that convenient in D, especially with assignments of anonymous/inline ones. You may want to add a layer of abstraction to the API you expose in D so that user D delegates are used from a second extern (C) delegate itself used by the C++ wrapper:

class BotanStuff {
    protected void delegate (string) ddg;
    protected BotanWrapper wrapr;

    this (void delegate (string) dg) {
        ddg   = dg;
        wrapr = new BotanWrapper (& this.cppDg);

    extern (C) void cppDg (immutable(char)* cStr) {
        import std.conv;
        dg (!string);

If you are planning to use Swig for your binding, this kind of wrapping may be conveniently done using custom typemaps.

On 08/15/2014 05:10 AM, Etienne Cimon wrote:
I'm looking into making a binding for the C++ API called Botan, and the
constructors in it take a std::function. I'm wondering if there's a D
equivalent for this binding to work out, or if I have to make a C++
wrapper as well?

Reply via email to