1 module lib_handler; 2 3 version(none): 4 5 nothrow @nogc extern(C): 6 7 import glob_opts; 8 //#include <ctype.h> // Needed for tolower functions 9 10 import constants; 11 import util; 12 13 version(Windows){ 14 //#include <windows.h> 15 // todo 16 alias soHandle_t = HINSTANCE; 17 } else { 18 import core.stdc.ctype; 19 import core.sys.posix.dlfcn; 20 21 alias soHandle_t = void *; 22 } 23 24 version(Windows) 25 { 26 enum string SHAREDLIBEXT = "dll"; 27 } else { 28 version(OSX){ 29 enum string SHAREDLIBEXT = "dylib"; 30 } else { 31 enum string SHAREDLIBEXT = "so"; 32 } 33 } 34 35 enum OSQP_NULL = null; 36 37 soHandle_t lh_load_lib(const char *libName) { 38 soHandle_t h = OSQP_NULL; 39 40 if (!libName) { 41 version(PRINTING){ 42 c_eprint("ERROR in %s: no library name given\n", __FUNCTION__.ptr); 43 } 44 return OSQP_NULL; 45 } 46 47 version(Windows){ 48 h = LoadLibrary (libName); 49 if (!h) { 50 version(PRINTING){ 51 c_eprint("ERROR in %s: Windows error while loading dynamic library %s, error = %d\n", 52 __FUNCTION__.ptr, libName, cast(int)GetLastError()); 53 } 54 } 55 } else { 56 h = dlopen (libName, RTLD_LAZY); 57 if (!h) { 58 version(PRINTING){ 59 c_eprint("ERROR in %s: Error while loading dynamic library %s: %s\n", __FUNCTION__.ptr, libName, dlerror()); 60 } 61 } 62 } 63 64 return h; 65 } /* lh_load_lib */ 66 67 68 c_int lh_unload_lib (soHandle_t h) { 69 c_int rc = 1; 70 71 version (Windows){ 72 rc = FreeLibrary (h); 73 rc = ! rc; 74 } else { 75 rc = dlclose (h); 76 } 77 78 return rc; 79 } /* LSL_unLoadLib */ 80 81 82 version (Windows){ 83 alias symtype = FARPROC; 84 } else { 85 //typedef void* symtype; 86 alias symtype = void*; 87 } 88 /** Loads a symbol from a dynamically linked library. 89 * This function is not defined in the header to allow a workaround for the problem that dlsym returns an object instead of a function pointer. 90 * However, Windows also needs special care. 91 * 92 * The method does six attempts to load the symbol. Next to its given name, it also tries variations of lower case and upper case form and with an extra underscore. 93 * @param h Handle of dynamically linked library. 94 * @param symName Name of the symbol to load. 95 * @return A pointer to the symbol, or OSQP_NULL if not found. 96 */ 97 symtype lh_load_sym (soHandle_t h, char *symName) { 98 symtype s; 99 char *from; 100 char *to; 101 char *tripSym; 102 char* err; 103 char [257] lcbuf; 104 char [257]ucbuf; 105 char [257]ocbuf; 106 size_t symLen; 107 int trip; 108 109 s = OSQP_NULL; 110 err = OSQP_NULL; 111 112 /* search in this order: 113 * 1. original 114 * 2. lower_ 115 * 3. upper_ 116 * 4. original_ 117 * 5. lower 118 * 6. upper 119 */ 120 121 symLen = 0; 122 for (trip = 1; trip <= 6; trip++) { 123 switch (trip) { 124 case 1: /* original */ 125 tripSym = cast(char*)symName; 126 break; 127 case 2: /* lower_ */ 128 for (from = cast(char*)symName, to = cast(char*)lcbuf; *from; from++, to++) { 129 *to = cast(char)tolower(*from); // todo : may cause data loss 130 } 131 symLen = from - symName; 132 *to++ = '_'; 133 *to = '\0'; 134 tripSym = cast(char*)lcbuf; 135 break; 136 case 3: /* upper_ */ 137 for (from = cast(char*)symName, to = cast(char*)ucbuf; *from; from++, to++) { 138 *to = cast(char)toupper(*from); 139 } 140 *to++ = '_'; 141 *to = '\0'; 142 tripSym = cast(char*)ucbuf; 143 break; 144 case 4: /* original_ */ 145 c_strcpy(cast(char*)ocbuf, symName); 146 ocbuf[symLen] = '_'; 147 ocbuf[symLen+1] = '\0'; 148 tripSym = cast(char*)ocbuf; 149 break; 150 case 5: /* lower */ 151 lcbuf[symLen] = '\0'; 152 tripSym = cast(char*)lcbuf; 153 break; 154 case 6: /* upper */ 155 ucbuf[symLen] = '\0'; 156 tripSym = cast(char*)ucbuf; 157 break; 158 default: 159 tripSym = cast(char*)symName; 160 } /* end switch */ 161 version(Windows){ 162 s = GetProcAddress (h, tripSym); 163 if (s) { 164 return s; 165 } else { 166 version(PRINTING){ 167 c_eprint("ERROR in %s: Cannot find symbol %s in dynamic library, error = %d\n", __FUNCTION__.ptr, 168 symName, cast(int)GetLastError()); 169 } 170 } 171 } else { 172 s = dlsym (h, tripSym); 173 err = dlerror(); /* we have only one chance; a successive call to dlerror() returns OSQP_NULL */ 174 if (err) { 175 version(PRINTING){ 176 c_eprint("ERROR in %s: Cannot find symbol %s in dynamic library, error = %s\n", __FUNCTION__.ptr, 177 symName, err); 178 } 179 } else { 180 return s; 181 } 182 } 183 } /* end loop over symbol name variations */ 184 185 return OSQP_NULL; 186 } /* lh_load_sym */