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