1 /// OpenGL loader 2 module gfx.bindings.opengl.loader; 3 4 // Dynamic bindings facility 5 6 /// A handle to a shared library 7 alias SharedLib = void*; 8 /// A handle to a shared library symbol 9 alias SharedSym = void*; 10 11 /// Opens a shared library. 12 /// Return null in case of failure. 13 SharedLib openSharedLib(string name); 14 15 /// Load a symbol from a shared library. 16 /// Return null in case of failure. 17 SharedSym loadSharedSym(SharedLib lib, string name); 18 19 /// Close a shared library 20 void closeSharedLib(SharedLib lib); 21 22 23 /// Generic Dynamic lib symbol loader. 24 /// Symbols loaded with such loader must be cast to the appropriate function type. 25 alias SymbolLoader = SharedSym delegate (in string name); 26 27 28 version(Posix) 29 { 30 import std..string : toStringz; 31 import core.sys.posix.dlfcn; 32 33 SharedLib openSharedLib(string name) 34 { 35 return dlopen(toStringz(name), RTLD_LAZY); 36 } 37 38 SharedSym loadSharedSym(SharedLib lib, string name) 39 { 40 return dlsym(lib, toStringz(name)); 41 } 42 43 void closeSharedLib(SharedLib lib) 44 { 45 dlclose(lib); 46 } 47 } 48 version(Windows) 49 { 50 import std..string : toStringz; 51 import core.sys.windows.winbase; 52 53 SharedLib openSharedLib(string name) 54 { 55 return LoadLibraryA(toStringz(name)); 56 } 57 58 SharedSym loadSharedSym(SharedLib lib, string name) 59 { 60 return GetProcAddress(lib, toStringz(name)); 61 } 62 63 void closeSharedLib(SharedLib lib) 64 { 65 FreeLibrary(lib); 66 } 67 } 68 69 /// Utility that open a shared library and load symbols from it. 70 class SharedLibLoader 71 { 72 import std.typecons : Flag, Yes, No; 73 private SharedLib _lib; 74 private string _libName; 75 76 /// Load the shared libraries and call bindSymbols if succesful. 77 void load (string[] libNames) 78 { 79 foreach (ln; libNames) 80 { 81 _lib = openSharedLib(ln); 82 if (_lib) 83 { 84 _libName = ln; 85 break; 86 } 87 } 88 if (!_lib) 89 { 90 import std.conv : to; 91 throw new Exception( 92 "Cannot load one of shared libs " ~ libNames.to!string 93 ); 94 } 95 bindSymbols(); 96 } 97 98 /// Direct handle access 99 public @property SharedLib handle() 100 { 101 return _lib; 102 } 103 104 /// Returns whether the shared library is open. 105 public @property bool loaded() const 106 { 107 return _lib !is null; 108 } 109 110 /// Returns the name of the shared library that was open. 111 /// Empty string if not loaded. 112 public @property string libName() const 113 { 114 return _libName; 115 } 116 117 /// Bind a symbol, using the function pointer symbol name. 118 void bind(alias f)(Flag!"optional" optional = No.optional) 119 { 120 immutable name = f.stringof; 121 if (f !is null) 122 { 123 throw new Exception("Tentative to bind already bound symbol "~ name); 124 } 125 auto sym = loadSharedSym(_lib, name); 126 if (!sym && !optional) 127 { 128 throw new Exception("Cannot load symbol "~name~" from "~_libName~"."); 129 } 130 f = cast(typeof(f)) sym; 131 } 132 133 /// Subclasses can override this to bind all the necessary symbols. 134 /// Default implementation does nothing. 135 void bindSymbols() 136 {} 137 }