#include "lib_handler.h" #include // Needed for tolower functions #include "constants.h" #include "util.h" soHandle_t lh_load_lib(const char *libName) { soHandle_t h = OSQP_NULL; if (!libName) { #ifdef PRINTING c_eprint("no library name given"); #endif return OSQP_NULL; } #ifdef IS_WINDOWS h = LoadLibrary (libName); if (!h) { #ifdef PRINTING c_eprint("Windows error while loading dynamic library %s, error = %d", libName, (int)GetLastError()); #endif } #else h = dlopen (libName, RTLD_LAZY); if (!h) { #ifdef PRINTING c_eprint("Error while loading dynamic library %s: %s", libName, dlerror()); #endif } #endif return h; } /* lh_load_lib */ c_int lh_unload_lib (soHandle_t h) { c_int rc = 1; #ifdef IS_WINDOWS rc = FreeLibrary (h); rc = ! rc; #else rc = dlclose (h); #endif return rc; } /* LSL_unLoadLib */ #ifdef IS_WINDOWS typedef FARPROC symtype; #else typedef void* symtype; #endif /** Loads a symbol from a dynamically linked library. * 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. * However, Windows also needs special care. * * 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. * @param h Handle of dynamically linked library. * @param symName Name of the symbol to load. * @return A pointer to the symbol, or OSQP_NULL if not found. */ symtype lh_load_sym (soHandle_t h, const char *symName) { symtype s; const char *from; char *to; const char *tripSym; char* err; char lcbuf[257]; char ucbuf[257]; char ocbuf[257]; size_t symLen; int trip; s = OSQP_NULL; err = OSQP_NULL; /* search in this order: * 1. original * 2. lower_ * 3. upper_ * 4. original_ * 5. lower * 6. upper */ symLen = 0; for (trip = 1; trip <= 6; trip++) { switch (trip) { case 1: /* original */ tripSym = symName; break; case 2: /* lower_ */ for (from = symName, to = lcbuf; *from; from++, to++) { *to = tolower(*from); } symLen = from - symName; *to++ = '_'; *to = '\0'; tripSym = lcbuf; break; case 3: /* upper_ */ for (from = symName, to = ucbuf; *from; from++, to++) { *to = toupper(*from); } *to++ = '_'; *to = '\0'; tripSym = ucbuf; break; case 4: /* original_ */ c_strcpy(ocbuf, symName); ocbuf[symLen] = '_'; ocbuf[symLen+1] = '\0'; tripSym = ocbuf; break; case 5: /* lower */ lcbuf[symLen] = '\0'; tripSym = lcbuf; break; case 6: /* upper */ ucbuf[symLen] = '\0'; tripSym = ucbuf; break; default: tripSym = symName; } /* end switch */ #ifdef IS_WINDOWS s = GetProcAddress (h, tripSym); if (s) { return s; } else { #ifdef PRINTING c_eprint("Cannot find symbol %s in dynamic library, error = %d", symName, (int)GetLastError()); #endif } #else s = dlsym (h, tripSym); err = dlerror(); /* we have only one chance; a successive call to dlerror() returns OSQP_NULL */ if (err) { #ifdef PRINTING c_eprint("Cannot find symbol %s in dynamic library, error = %s", symName, err); #endif } else { return s; } #endif } /* end loop over symbol name variations */ return OSQP_NULL; } /* lh_load_sym */