1 2 module llvm.util.shlib; 3 4 private 5 { 6 import std.string : toStringz, fromStringz; 7 import std.conv : to; 8 } 9 10 final class SharedLibLoadException : Exception 11 { 12 @safe pure nothrow 13 this(string msg) 14 { 15 super(msg); 16 } 17 } 18 19 version(Posix) 20 { 21 private import core.sys.posix.dlfcn; 22 23 alias void* SharedLibHandle; 24 25 version(OSX) 26 { 27 string libPrefix = "lib"; 28 string libSuffix = "dylib"; 29 } 30 else 31 { 32 string libPrefix = "lib"; 33 string libSuffix = "so"; 34 } 35 36 pragma(lib, "dl"); 37 } 38 else version(Windows) 39 { 40 private import core.sys.windows.windows; 41 private import std.path : dirName; 42 43 alias HMODULE SharedLibHandle; 44 45 string libPrefix = ""; 46 string libSuffix = "dll"; 47 } else { 48 static assert(false, "Shared libraries unimplemented for this system."); 49 } 50 51 class SharedLib 52 { 53 private SharedLibHandle handle; 54 private string libName; 55 56 public this(string libName) 57 { 58 this.libName = libName; 59 } 60 61 public void load() 62 { 63 return loadFile(libName); 64 } 65 66 private void loadFile(string file) 67 { 68 version(Posix) 69 { 70 if((handle = dlopen(file.toStringz(), RTLD_NOW)) is null) 71 { 72 throw new SharedLibLoadException("Failed to load library "~file~": "~dlerror().fromStringz().idup); 73 } 74 } 75 else version(Windows) 76 { 77 if((handle = LoadLibraryA(file.toStringz())) is null) 78 { 79 LPCSTR error; 80 DWORD tchar_length = FormatMessageA( 81 FORMAT_MESSAGE_ALLOCATE_BUFFER | 82 FORMAT_MESSAGE_FROM_SYSTEM | 83 FORMAT_MESSAGE_IGNORE_INSERTS, 84 null, 85 GetLastError(), 86 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), 87 cast(char*) &error, 88 0, 89 null); 90 scope(exit) LocalFree(cast(HLOCAL) error); 91 92 throw new SharedLibLoadException("Failed to load library "~file~": "~error[0..tchar_length]); 93 } 94 } 95 } 96 97 public void unload() 98 { 99 version(Posix) 100 { 101 if(handle !is null) 102 { 103 dlclose(handle); 104 } 105 } 106 else 107 { 108 if(handle !is null) 109 { 110 FreeLibrary(handle); 111 } 112 } 113 } 114 115 public T loadSymbol(T)(string symbol) 116 { 117 version(Posix) 118 { 119 return cast(T) dlsym(handle, symbol.toStringz()); 120 } 121 else 122 { 123 return cast(T) GetProcAddress(handle, symbol.toStringz()); 124 } 125 } 126 }