BsDynLib.cpp 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  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. DWORD lastError = GetLastError();
  48. if(!m_hInst)
  49. {
  50. BS_EXCEPT(InternalErrorException,
  51. "Could not load dynamic library " + mName +
  52. ". System Error: " + dynlibError());
  53. }
  54. }
  55. void DynLib::unload()
  56. {
  57. if(!m_hInst)
  58. return;
  59. if(DYNLIB_UNLOAD(m_hInst))
  60. {
  61. BS_EXCEPT(InternalErrorException,
  62. "Could not unload dynamic library " + mName +
  63. ". System Error: " + dynlibError());
  64. }
  65. }
  66. void* DynLib::getSymbol(const String& strName) const
  67. {
  68. if(!m_hInst)
  69. return nullptr;
  70. return (void*)DYNLIB_GETSYM(m_hInst, strName.c_str());
  71. }
  72. String DynLib::dynlibError()
  73. {
  74. #if BS_PLATFORM == BS_PLATFORM_WIN32
  75. LPVOID lpMsgBuf;
  76. FormatMessage(
  77. FORMAT_MESSAGE_ALLOCATE_BUFFER |
  78. FORMAT_MESSAGE_FROM_SYSTEM |
  79. FORMAT_MESSAGE_IGNORE_INSERTS,
  80. NULL,
  81. GetLastError(),
  82. MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
  83. (LPTSTR) &lpMsgBuf,
  84. 0,
  85. NULL
  86. );
  87. String ret = (char*)lpMsgBuf;
  88. // Free the buffer.
  89. LocalFree(lpMsgBuf);
  90. return ret;
  91. #elif BS_PLATFORM == BS_PLATFORM_LINUX || BS_PLATFORM == BS_PLATFORM_APPLE
  92. return String(dlerror());
  93. #else
  94. return String("");
  95. #endif
  96. }
  97. }