boilerplate generation
Carl Sturtivant
sturtivant at gmail.com
Sun Dec 29 14:27:59 PST 2013
On Sunday, 29 December 2013 at 22:01:19 UTC, Dicebot wrote:
> Does this look clean enough? (Not sure I have completely
> understood the question)
>
> /* export extern(C) int f( uint argc, A* argv) { return
> Wrapper!f(
> argc, argv); } */
>
> struct A {}
>
> int Wrapper(alias func, T...)(T args) { return 42; }
>
> template ExternC(alias existingFunc)
> {
> import std.string : format;
> import std.traits : ReturnType;
>
> static assert(is(typeof(&existingFunc) : int function(uint,
> A*)));
>
> mixin(format(
> "export extern(C) int %s(uint argc, A* argv) { return
> Wrapper!(%s)(argc, argv); }",
> __traits(identifier, existingFunc),
> __traits(identifier, existingFunc)
> ));
> }
>
> // to avoid name clash, assuming you have different module in
> real code
> struct X
> {
> static int fff(uint, A*)
> {
> return 42;
> }
> }
>
> mixin ExternC!(X.fff);
>
> pragma(msg, typeof(fff));
> // extern (C) int(uint argc, A* argv)
>
> void main()
> {
> }
Very nice. Only one problem: when I use dmd/win32 to build the
DLL, and analyze the resulting export, it's
_D5mixin43__T7ExternCS28_D5mixin1X3fffFkPS5mixin1AZiZ3fffUkPS5mixin1AZi
and not _fff or similar. So somehow the extern(C) hasn't led to a
C symbol.
More information about the Digitalmars-d-learn
mailing list