boilerplate generation

Dicebot public at dicebot.lv
Sun Dec 29 20:35:32 PST 2013


On Sunday, 29 December 2013 at 22:28:00 UTC, Carl Sturtivant 
wrote:
> 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.

Ah, yeah, have missed that. Such thing is expected if symbol is 
nested and can't have clear C mangling (then extern(C) only 
impacts ABI). It is kind of weird that this is also the case for 
mixin templates as those are injected into target scope but makes 
sense once you remember that even mixin templates conform symbol 
hygiene.

It can be forced by pragma(mangle) though. Updated code:

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*)));
	
	private enum name = __traits(identifier, existingFunc);
	
	mixin(format(
		q{pragma(mangle, "%s") export extern(C) int %s(uint argc, A* 
argv) { return Wrapper!(%s)(argc, argv); }},
		name,
		name,
		name
	));
}

// 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)

pragma(msg, fff.mangleof);
// fff

void main()
{}


More information about the Digitalmars-d-learn mailing list