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.


Reply via email to