import std.c.windows.windows; import std.stdio; import std.traits; import std.string; import std.utf; struct Symbol(char[] SymName, Ret, Params...) { alias Params Parameters; alias Ret ReturnValue; const char[] Name = SymName; extern(Windows) alias ReturnValue function(Params) FunctionType; } // FP_Function private template MixinMember(S) //S = Symbol template { mixin("public alias S.FunctionType FP_" ~ S.Name ~ ";"); mixin("public S.FunctionType " ~ S.Name ~ ";"); } private template MixinAllMembers(S, V...) { mixin MixinMember!(S); static if(V.length > 0) { mixin MixinAllMembers!(V); } } final class Module(char[] Path, Symbols...) { private HMODULE m_handle = null; public mixin MixinAllMembers!(Symbols); public this() { load(Path); initMembers(); } public ~this() { free(); } private void initMembers() { foreach (i, S; Symbols) { mixin(S.Name ~ " = getSymbol!(FP_" ~ S.Name ~ ")(S.Name);"); } } void load(char[] path) { // m_handle = LoadLibraryW(toUtf16z(path)); m_handle = LoadLibraryA(toStringz(path)); assert(m_handle); } void free() { if(m_handle != null) { FreeLibrary(m_handle); m_handle = null; } } public T getSymbol(T)(char[] sym) { return cast(T)getSymbol1(sym); } public void* getSymbol1(char[] sym) { return GetProcAddress(m_handle, toStringz(sym)); } } void main() { auto dll = new Module!("User32.dll", Symbol!("MessageBoxW", int, HWND, LPCWSTR, LPCWSTR, UINT), Symbol!("MessageBoxA", int, HWND, LPCSTR, LPCSTR, UINT) ); dll.MessageBoxW(null, "Hello! DLL! W", "Title W", MB_OK); dll.MessageBoxA(null, "Hello! DLL! A", "Title A", MB_OK); }