BsDynLib.cpp 2.9 KB

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