lib_handler.c 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. #include "lib_handler.h"
  2. #include <ctype.h> // Needed for tolower functions
  3. #include "constants.h"
  4. #include "util.h"
  5. soHandle_t lh_load_lib(const char *libName) {
  6. soHandle_t h = OSQP_NULL;
  7. if (!libName) {
  8. #ifdef PRINTING
  9. c_eprint("no library name given");
  10. #endif
  11. return OSQP_NULL;
  12. }
  13. #ifdef IS_WINDOWS
  14. h = LoadLibrary (libName);
  15. if (!h) {
  16. #ifdef PRINTING
  17. c_eprint("Windows error while loading dynamic library %s, error = %d",
  18. libName, (int)GetLastError());
  19. #endif
  20. }
  21. #else
  22. h = dlopen (libName, RTLD_LAZY);
  23. if (!h) {
  24. #ifdef PRINTING
  25. c_eprint("Error while loading dynamic library %s: %s", libName, dlerror());
  26. #endif
  27. }
  28. #endif
  29. return h;
  30. } /* lh_load_lib */
  31. c_int lh_unload_lib (soHandle_t h) {
  32. c_int rc = 1;
  33. #ifdef IS_WINDOWS
  34. rc = FreeLibrary (h);
  35. rc = ! rc;
  36. #else
  37. rc = dlclose (h);
  38. #endif
  39. return rc;
  40. } /* LSL_unLoadLib */
  41. #ifdef IS_WINDOWS
  42. typedef FARPROC symtype;
  43. #else
  44. typedef void* symtype;
  45. #endif
  46. /** Loads a symbol from a dynamically linked library.
  47. * 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.
  48. * However, Windows also needs special care.
  49. *
  50. * 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.
  51. * @param h Handle of dynamically linked library.
  52. * @param symName Name of the symbol to load.
  53. * @return A pointer to the symbol, or OSQP_NULL if not found.
  54. */
  55. symtype lh_load_sym (soHandle_t h, const char *symName) {
  56. symtype s;
  57. const char *from;
  58. char *to;
  59. const char *tripSym;
  60. char* err;
  61. char lcbuf[257];
  62. char ucbuf[257];
  63. char ocbuf[257];
  64. size_t symLen;
  65. int trip;
  66. s = OSQP_NULL;
  67. err = OSQP_NULL;
  68. /* search in this order:
  69. * 1. original
  70. * 2. lower_
  71. * 3. upper_
  72. * 4. original_
  73. * 5. lower
  74. * 6. upper
  75. */
  76. symLen = 0;
  77. for (trip = 1; trip <= 6; trip++) {
  78. switch (trip) {
  79. case 1: /* original */
  80. tripSym = symName;
  81. break;
  82. case 2: /* lower_ */
  83. for (from = symName, to = lcbuf; *from; from++, to++) {
  84. *to = tolower(*from);
  85. }
  86. symLen = from - symName;
  87. *to++ = '_';
  88. *to = '\0';
  89. tripSym = lcbuf;
  90. break;
  91. case 3: /* upper_ */
  92. for (from = symName, to = ucbuf; *from; from++, to++) {
  93. *to = toupper(*from);
  94. }
  95. *to++ = '_';
  96. *to = '\0';
  97. tripSym = ucbuf;
  98. break;
  99. case 4: /* original_ */
  100. c_strcpy(ocbuf, symName);
  101. ocbuf[symLen] = '_';
  102. ocbuf[symLen+1] = '\0';
  103. tripSym = ocbuf;
  104. break;
  105. case 5: /* lower */
  106. lcbuf[symLen] = '\0';
  107. tripSym = lcbuf;
  108. break;
  109. case 6: /* upper */
  110. ucbuf[symLen] = '\0';
  111. tripSym = ucbuf;
  112. break;
  113. default:
  114. tripSym = symName;
  115. } /* end switch */
  116. #ifdef IS_WINDOWS
  117. s = GetProcAddress (h, tripSym);
  118. if (s) {
  119. return s;
  120. } else {
  121. #ifdef PRINTING
  122. c_eprint("Cannot find symbol %s in dynamic library, error = %d",
  123. symName, (int)GetLastError());
  124. #endif
  125. }
  126. #else
  127. s = dlsym (h, tripSym);
  128. err = dlerror(); /* we have only one chance; a successive call to dlerror() returns OSQP_NULL */
  129. if (err) {
  130. #ifdef PRINTING
  131. c_eprint("Cannot find symbol %s in dynamic library, error = %s",
  132. symName, err);
  133. #endif
  134. } else {
  135. return s;
  136. }
  137. #endif
  138. } /* end loop over symbol name variations */
  139. return OSQP_NULL;
  140. } /* lh_load_sym */