Wrapping multiple extern (C) declarations in a template

Gary Willoughby via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Sat Dec 13 08:53:40 PST 2014


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.


More information about the Digitalmars-d-learn mailing list