BsDynLib.cpp 2.6 KB

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