On Saturday, 13 December 2014 at 16:34:42 UTC, aldanor wrote:
I'm writing bindings to a rather big C library where the return values of almost all functions indicate the possibility of an error (exception).

Assuming there's a C header, "foo.h" with functions "f1", "f2", etc, I want to have a corresponding D module, "foo.d" which would provide the "f1", "f2" that wrap the C functions and throw exceptions if an error is encountered (which is implemented in an errorCheck template which checks the return value and then gets the exception info via C API).

My current naive solution looks like this:

/* foo.h */

int f1(...);
int f2(...);

*** foo.d ***

private extern (C) nothrow {
    pragma(mangle, "f1")
    int c_f(...);
    public alias errorCheck!c_f1 f1;

    pragma(mangle, "f2")
    int c_f2(...);
    public alias errorCheck!c_f2 f2;
}

This way, one can "import foo" and use the same API as in C, but with proper exception handling.

Since there is almost a thousand declarations, this leads to a lot of manual work and boilerplate. I guess the wrapping part itself (aliasing the wrapped functions) could be automated via a mixin template, but how would one go around repetitive pragma(mangle) (which I thought is needed so that private extern declarations have different names and don't clash with the wrapped ones )?

Personally i wouldn't go this route. I would create foo.d as a C to D translation only so it can be imported and used like in C. Then i would create another module which imports this to create your new OOP API adding features and excepions, etc.

This allows the best of both worlds, keep the C api intact for use in D and create a new clean OOP API for whatever your needs are.

Reply via email to