diff --git a/source/derelict/util/buildhelper.d b/source/derelict/util/buildhelper.d new file mode 100644 index 0000000..d438bdc --- /dev/null +++ b/source/derelict/util/buildhelper.d @@ -0,0 +1,28 @@ +module derelict.util.buildhelper; + +import std.traits; + +template BuildLoadSymbols(alias T, bool doThrow = false) +{ + string _buildLoadSymbols(alias T, bool doThrow = false)() + { + static if(doThrow) + enum dthrow = "true"; + else + enum dthrow = "false"; + + string bindlist = "\n{"; + foreach(mem; __traits(derivedMembers, T)) + { + static if( isFunctionPointer!(__traits(getMember, T, mem)) /*&& !is(typeof(__traits(getMember, T, mem)) == immutable)*/) + { + bindlist ~= "\tbindFunc(" ~ mem ~ ", \"" ~ mem ~ "\", " ~ dthrow ~ ");\n"; + } + } + bindlist ~= "}"; + return bindlist; + } + + enum BuildLoadSymbols = _buildLoadSymbols!(T, doThrow)(); +} + diff --git a/source/derelict/util/loader.d b/source/derelict/util/loader.d index e3bf854..c62d955 100644 --- a/source/derelict/util/loader.d +++ b/source/derelict/util/loader.d @@ -346,5 +346,26 @@ abstract class SharedLibLoader { void* func = loadSymbol(funcName, doThrow); *ptr = func; } + + /++ + Subclasses can use this to bind a function pointer to a symbol in the + shared library. + + Params: + fun = function pointer that will be used as the bind + point. + funcName = The name of the symbol to be bound. + doThrow = If true, a SymbolLoadException will be thrown if the symbol + is missing. If false, no exception will be thrown and the + ptr parameter will be set to null. + Throws: SymbolLoadException if doThrow is true and a the symbol + specified by funcName is missing from the shared library. + +/ + import std.traits; + final void bindFunc(TFUN)(ref TFUN fun, string funcName, bool doThrow = true) + if(isFunctionPointer!(TFUN)){ + void* func = loadSymbol(funcName, doThrow); + fun = cast(TFUN)func; + } } -} \ No newline at end of file +}