CmDynLib.cpp 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. #include "CmDynLib.h"
  2. #include "CmException.h"
  3. #if CM_PLATFORM == CM_PLATFORM_WIN32
  4. # define WIN32_LEAN_AND_MEAN
  5. # if !defined(NOMINMAX) && defined(_MSC_VER)
  6. # define NOMINMAX // required to stop windows.h messing up std::min
  7. # endif
  8. # include <windows.h>
  9. #endif
  10. #if CM_PLATFORM == CM_PLATFORM_APPLE
  11. # include "macUtils.h"
  12. # include <dlfcn.h>
  13. #endif
  14. namespace CamelotFramework
  15. {
  16. DynLib::DynLib(const String& name)
  17. {
  18. mName = name;
  19. m_hInst = NULL;
  20. }
  21. DynLib::~DynLib()
  22. {
  23. }
  24. void DynLib::load()
  25. {
  26. if(m_hInst)
  27. return;
  28. String name = mName;
  29. #if CM_PLATFORM == CM_PLATFORM_LINUX
  30. // dlopen() does not add .so to the filename, like windows does for .dll
  31. if (name.substr(name.length() - 3, 3) != ".so")
  32. name += ".so";
  33. #elif CM_PLATFORM == CM_PLATFORM_APPLE
  34. // dlopen() does not add .dylib to the filename, like windows does for .dll
  35. if (name.substr(name.length() - 6, 6) != ".dylib")
  36. name += ".dylib";
  37. #elif CM_PLATFORM == CM_PLATFORM_WIN32
  38. // Although LoadLibraryEx will add .dll itself when you only specify the library name,
  39. // if you include a relative path then it does not. So, add it to be sure.
  40. if (name.substr(name.length() - 4, 4) != ".dll")
  41. name += ".dll";
  42. #endif
  43. m_hInst = (DYNLIB_HANDLE)DYNLIB_LOAD(name.c_str());
  44. if(!m_hInst)
  45. {
  46. CM_EXCEPT(InternalErrorException,
  47. "Could not load dynamic library " + mName +
  48. ". System Error: " + dynlibError());
  49. }
  50. }
  51. void DynLib::unload()
  52. {
  53. if(!m_hInst)
  54. return;
  55. if(DYNLIB_UNLOAD(m_hInst))
  56. {
  57. CM_EXCEPT(InternalErrorException,
  58. "Could not unload dynamic library " + mName +
  59. ". System Error: " + dynlibError());
  60. }
  61. }
  62. void* DynLib::getSymbol(const String& strName) const
  63. {
  64. if(!m_hInst)
  65. return nullptr;
  66. return (void*)DYNLIB_GETSYM(m_hInst, strName.c_str());
  67. }
  68. String DynLib::dynlibError()
  69. {
  70. #if CM_PLATFORM == CM_PLATFORM_WIN32
  71. LPVOID lpMsgBuf;
  72. FormatMessage(
  73. FORMAT_MESSAGE_ALLOCATE_BUFFER |
  74. FORMAT_MESSAGE_FROM_SYSTEM |
  75. FORMAT_MESSAGE_IGNORE_INSERTS,
  76. NULL,
  77. GetLastError(),
  78. MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
  79. (LPTSTR) &lpMsgBuf,
  80. 0,
  81. NULL
  82. );
  83. String ret = (char*)lpMsgBuf;
  84. // Free the buffer.
  85. LocalFree(lpMsgBuf);
  86. return ret;
  87. #elif CM_PLATFORM == CM_PLATFORM_LINUX || CM_PLATFORM == CM_PLATFORM_APPLE
  88. return String(dlerror());
  89. #else
  90. return String("");
  91. #endif
  92. }
  93. }