1 module dynamic; 2 3 mixin template dynamicBinding(alias mod) 4 { 5 import core.runtime : Runtime; 6 import std.traits : ReturnType, ParameterTypeTuple, functionLinkage; 7 import std.format : format; 8 9 static foreach (proto; prototypes!mod) { 10 mixin(q{ 11 extern(%2$s) alias P_%1$s = ReturnType!proto function(ParameterTypeTuple!proto); 12 P_%1$s p_%1$s; 13 extern(%2$s) ReturnType!proto %1$s(ParameterTypeTuple!proto params) { 14 assert(p_%1$s !is null, "Function not loaded: %1$s"); 15 return p_%1$s(params); 16 } 17 }.format(__traits(identifier, proto), functionLinkage!proto)); 18 } 19 20 void loadBinding(scope string[] library_files) 21 { 22 import std.conv : to; 23 import std.format : format; 24 import std.utf : toUTF16z; 25 import std..string : toStringz; 26 version (Windows) import core.sys.windows.windows : LoadLibraryW; 27 else import core.sys.posix.dlfcn : dlopen, RTLD_LAZY; 28 29 foreach (f; library_files) { 30 version (Windows) void* lib = LoadLibraryW(f.toUTF16z); 31 else void* lib = dlopen(f.toStringz(), RTLD_LAZY); 32 if (!lib) continue; 33 34 foreach (proto; prototypes!mod) { 35 mixin(q{ 36 p_%1$s = cast(P_%1$s)loadProc(lib, proto.mangleof); 37 if (!p_%1$s) 38 throw new Exception( 39 format("Failed to load function '%%s' from %1$s", 40 proto.mangleof)); 41 }.format(__traits(identifier, proto))); 42 } 43 return; 44 } 45 46 throw new Exception(format("Failed to load any of the shared library candidates: %(%s, %)", library_files)); 47 } 48 } 49 50 /// private 51 template prototypes(alias mod) 52 { 53 import std.meta : AliasSeq, staticMap; 54 55 alias Overloads(string name) = AliasSeq!(__traits(getOverloads, mod, name)); 56 alias functions = staticMap!(Overloads, AliasSeq!(__traits(allMembers, mod))); 57 58 /*template impl(size_t idx) { 59 static if (idx < members.length) { 60 alias impl = AliasSeq!(members[i], impl 61 } else alias impl = AliasSeq!(); 62 }*/ 63 alias prototypes = functions; 64 } 65 66 /// private 67 void* loadProc(void* lib, string name) 68 { 69 import std..string : toStringz; 70 71 version (Windows) { 72 import core.sys.windows.windows; 73 return GetProcAddress(lib, name.toStringz()); 74 } else { 75 import core.sys.posix.dlfcn : dlsym; 76 return dlsym(lib, name.toStringz()); 77 } 78 }