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.