// dll.d // A simple DLL wrapper // Author: Wei Li (wstring@gmail.com) import std.c.windows.windows; import std.stdio; import std.traits; import std.string; struct Symbol(char[] Sym, Func) { const char[] Name = Sym; extern(Windows) alias ReturnType!(Func) function(ParameterTypeTuple!(Func)) FunctionType; // extern(Windows) alias FuncType FunctionType // Why is this Invalid? DMD's bug? } private template MixinMembers(S, V...) { mixin("alias S.FunctionType FP_" ~ S.Name ~ ";"); mixin("S.FunctionType " ~ S.Name ~ ";"); static if(V.length > 0) mixin MixinMembers!(V); } final class Module(char[] Path, Symbols...) { private HMODULE m_handle = null; public mixin MixinMembers!(Symbols); public this() { load(); initSymbols(); } public ~this() { free(); } private void initSymbols() { foreach (i, S; Symbols) { mixin(S.Name ~ " = getSymbol!(FP_" ~ S.Name ~ ")(S.Name);"); } } private void load() { m_handle = LoadLibraryA(toStringz(Path)); assert(m_handle); } private void free() { FreeLibrary(m_handle); } public T getSymbol(T)(char[] sym) { return cast(T)getSymbolAddress(sym); } public void* getSymbolAddress(char[] sym) { return GetProcAddress(m_handle, toStringz(sym)); } } void main() { scope auto dll = new Module!("User32.dll", Symbol!("MessageBoxW", int function(HWND, LPCWSTR, LPCWSTR, UINT)), Symbol!("MessageBoxA", int function(HWND, LPCSTR, LPCSTR, UINT)) ); dll.MessageBoxW(null, "Hello! DLL! ", "Hello from MessageBoxW", MB_OK); dll.MessageBoxA(null, "Hello! DLL! ", "Hello from MessageBoxA", MB_OK); }