DynamicLoader.cxx 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331
  1. /*=========================================================================
  2. Program: KWSys - Kitware System Library
  3. Module: $RCSfile$
  4. Copyright (c) Kitware, Inc., Insight Consortium. All rights reserved.
  5. See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
  6. This software is distributed WITHOUT ANY WARRANTY; without even
  7. the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
  8. PURPOSE. See the above copyright notices for more information.
  9. =========================================================================*/
  10. #include "kwsysPrivate.h"
  11. #include KWSYS_HEADER(DynamicLoader.hxx)
  12. #include KWSYS_HEADER(Configure.hxx)
  13. // Work-around CMake dependency scanning limitation. This must
  14. // duplicate the above list of headers.
  15. #if 0
  16. # include "DynamicLoader.hxx.in"
  17. # include "Configure.hxx.in"
  18. #endif
  19. // This file is actually 3 different implementations.
  20. // 1. HP machines which uses shl_load
  21. // 2. Mac OS X 10.2.x and earlier which uses NSLinkModule
  22. // 3. Windows which uses LoadLibrary
  23. // 4. Most unix systems (including Mac OS X 10.3 and later) which use dlopen (default)
  24. // Each part of the ifdef contains a complete implementation for
  25. // the static methods of DynamicLoader.
  26. namespace KWSYS_NAMESPACE
  27. {
  28. //----------------------------------------------------------------------------
  29. DynamicLoader::DynamicLoader()
  30. {
  31. }
  32. //----------------------------------------------------------------------------
  33. DynamicLoader::~DynamicLoader()
  34. {
  35. }
  36. }
  37. // ---------------------------------------------------------------
  38. // 1. Implementation for HPUX machines
  39. #ifdef __hpux
  40. #include <dl.h>
  41. #define DYNAMICLOADER_DEFINED 1
  42. namespace KWSYS_NAMESPACE
  43. {
  44. //----------------------------------------------------------------------------
  45. LibHandle DynamicLoader::OpenLibrary(const char* libname )
  46. {
  47. return shl_load(libname, BIND_DEFERRED | DYNAMIC_PATH, 0L);
  48. }
  49. //----------------------------------------------------------------------------
  50. int DynamicLoader::CloseLibrary(LibHandle lib)
  51. {
  52. return !shl_unload(lib);
  53. }
  54. //----------------------------------------------------------------------------
  55. DynamicLoaderFunction
  56. DynamicLoader::GetSymbolAddress(LibHandle lib, const char* sym)
  57. {
  58. void* addr;
  59. int status;
  60. status = shl_findsym (&lib, sym, TYPE_PROCEDURE, &addr);
  61. void* result = (status < 0) ? (void*)0 : addr;
  62. // Hack to cast pointer-to-data to pointer-to-function.
  63. return *reinterpret_cast<DynamicLoaderFunction*>(&result);
  64. }
  65. //----------------------------------------------------------------------------
  66. const char* DynamicLoader::LibPrefix()
  67. {
  68. return "lib";
  69. }
  70. //----------------------------------------------------------------------------
  71. const char* DynamicLoader::LibExtension()
  72. {
  73. return ".sl";
  74. }
  75. //----------------------------------------------------------------------------
  76. const char* DynamicLoader::LastError()
  77. {
  78. // TODO: Need implementation with errno/strerror
  79. /* If successful, shl_findsym returns an integer (int) value zero. If
  80. * shl_findsym cannot find sym, it returns -1 and sets errno to zero.
  81. * If any other errors occur, shl_findsym returns -1 and sets errno to one
  82. * of these values (defined in <errno.h>):
  83. * ENOEXEC
  84. * A format error was detected in the specified library.
  85. * ENOSYM
  86. * A symbol on which sym depends could not be found.
  87. * EINVAL
  88. * The specified handle is invalid.
  89. */
  90. return 0;
  91. }
  92. } // namespace KWSYS_NAMESPACE
  93. #endif //__hpux
  94. // ---------------------------------------------------------------
  95. // 2. Implementation for Mac OS X 10.2.x and earlier
  96. #ifdef __APPLE__
  97. #if MAC_OS_X_VERSION_MIN_REQUIRED < 1030
  98. #include <mach-o/dyld.h>
  99. #define DYNAMICLOADER_DEFINED 1
  100. namespace KWSYS_NAMESPACE
  101. {
  102. //----------------------------------------------------------------------------
  103. LibHandle DynamicLoader::OpenLibrary(const char* libname )
  104. {
  105. NSObjectFileImageReturnCode rc;
  106. NSObjectFileImage image = 0;
  107. rc = NSCreateObjectFileImageFromFile(libname, &image);
  108. if(!image)
  109. {
  110. return 0;
  111. }
  112. return NSLinkModule(image, libname, NSLINKMODULE_OPTION_BINDNOW);
  113. }
  114. //----------------------------------------------------------------------------
  115. int DynamicLoader::CloseLibrary( LibHandle lib)
  116. {
  117. bool success = NSUnLinkModule(lib, NSUNLINKMODULE_OPTION_NONE);
  118. return success;
  119. }
  120. //----------------------------------------------------------------------------
  121. DynamicLoaderFunction DynamicLoader::GetSymbolAddress(LibHandle /* lib */, const char* sym)
  122. {
  123. void *result=0;
  124. if(NSIsSymbolNameDefined(sym))
  125. {
  126. NSSymbol symbol= NSLookupAndBindSymbol(sym);
  127. if(symbol)
  128. {
  129. result = NSAddressOfSymbol(symbol);
  130. }
  131. }
  132. // Hack to cast pointer-to-data to pointer-to-function.
  133. return *reinterpret_cast<DynamicLoaderFunction*>(&result);
  134. }
  135. //----------------------------------------------------------------------------
  136. const char* DynamicLoader::LibPrefix()
  137. {
  138. return "";
  139. }
  140. //----------------------------------------------------------------------------
  141. const char* DynamicLoader::LibExtension()
  142. {
  143. return ".dylib";
  144. }
  145. //----------------------------------------------------------------------------
  146. const char* DynamicLoader::LastError()
  147. {
  148. return 0;
  149. }
  150. } // namespace KWSYS_NAMESPACE
  151. #endif //MAC_OS_X_VERSION_MIN_REQUIRED < 1030
  152. #endif // __APPLE__
  153. // ---------------------------------------------------------------
  154. // 3. Implementation for Windows win32 code
  155. #ifdef _WIN32
  156. #include <windows.h>
  157. #define DYNAMICLOADER_DEFINED 1
  158. namespace KWSYS_NAMESPACE
  159. {
  160. //----------------------------------------------------------------------------
  161. LibHandle DynamicLoader::OpenLibrary(const char* libname)
  162. {
  163. LibHandle lh;
  164. #ifdef UNICODE
  165. wchar_t libn[MB_CUR_MAX];
  166. mbstowcs(libn, libname, MB_CUR_MAX);
  167. lh = LoadLibrary(libn);
  168. #else
  169. lh = LoadLibrary(libname);
  170. #endif
  171. return lh;
  172. }
  173. //----------------------------------------------------------------------------
  174. int DynamicLoader::CloseLibrary(LibHandle lib)
  175. {
  176. return (int)FreeLibrary(lib);
  177. }
  178. //----------------------------------------------------------------------------
  179. DynamicLoaderFunction DynamicLoader::GetSymbolAddress(LibHandle lib, const char* sym)
  180. {
  181. void *result;
  182. #ifdef UNICODE
  183. wchar_t wsym[MB_CUR_MAX];
  184. mbstowcs(wsym, sym, MB_CUR_MAX);
  185. result = GetProcAddress(lib, wsym);
  186. #else
  187. result = (void*)GetProcAddress(lib, sym);
  188. #endif
  189. // Hack to cast pointer-to-data to pointer-to-function.
  190. return *reinterpret_cast<DynamicLoaderFunction*>(&result);
  191. }
  192. //----------------------------------------------------------------------------
  193. const char* DynamicLoader::LibPrefix()
  194. {
  195. return "";
  196. }
  197. //----------------------------------------------------------------------------
  198. const char* DynamicLoader::LibExtension()
  199. {
  200. return ".dll";
  201. }
  202. //----------------------------------------------------------------------------
  203. const char* DynamicLoader::LastError()
  204. {
  205. LPVOID lpMsgBuf;
  206. FormatMessage(
  207. FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
  208. NULL,
  209. GetLastError(),
  210. MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
  211. (LPTSTR) &lpMsgBuf,
  212. 0,
  213. NULL
  214. );
  215. static char* str = 0;
  216. delete [] str;
  217. str = strcpy(new char[strlen((char*)lpMsgBuf)+1], (char*)lpMsgBuf);
  218. // Free the buffer.
  219. LocalFree( lpMsgBuf );
  220. return str;
  221. }
  222. } // namespace KWSYS_NAMESPACE
  223. #endif //_WIN32
  224. // ---------------------------------------------------------------
  225. // 4. Implementation for default UNIX machines.
  226. // if nothing has been defined then use this
  227. #ifndef DYNAMICLOADER_DEFINED
  228. #define DYNAMICLOADER_DEFINED 1
  229. // Setup for most unix machines
  230. #include <dlfcn.h>
  231. namespace KWSYS_NAMESPACE
  232. {
  233. //----------------------------------------------------------------------------
  234. LibHandle DynamicLoader::OpenLibrary(const char* libname )
  235. {
  236. return dlopen(libname, RTLD_LAZY);
  237. }
  238. //----------------------------------------------------------------------------
  239. int DynamicLoader::CloseLibrary(LibHandle lib)
  240. {
  241. if (lib)
  242. {
  243. // The function dlclose() returns 0 on success, and non-zero on error.
  244. return !(int)dlclose(lib);
  245. }
  246. // else
  247. return 0;
  248. }
  249. //----------------------------------------------------------------------------
  250. DynamicLoaderFunction DynamicLoader::GetSymbolAddress(LibHandle lib, const char* sym)
  251. {
  252. void* result = dlsym(lib, sym);
  253. // Hack to cast pointer-to-data to pointer-to-function.
  254. return *reinterpret_cast<DynamicLoaderFunction*>(&result);
  255. }
  256. //----------------------------------------------------------------------------
  257. const char* DynamicLoader::LibPrefix()
  258. {
  259. return "lib";
  260. }
  261. //----------------------------------------------------------------------------
  262. const char* DynamicLoader::LibExtension()
  263. {
  264. return ".so";
  265. }
  266. //----------------------------------------------------------------------------
  267. const char* DynamicLoader::LastError()
  268. {
  269. return dlerror();
  270. }
  271. } // namespace KWSYS_NAMESPACE
  272. #endif