1//************************************ bs::framework - Copyright 2018 Marko Pintera **************************************//
2//*********** Licensed under the MIT license. See LICENSE.md for full terms. This notice is not to be removed. ***********//
3#include "Utility/BsDynLib.h"
4#include "Error/BsException.h"
5
6#if BS_PLATFORM == BS_PLATFORM_WIN32
7 #define WIN32_LEAN_AND_MEAN
8 #if !defined(NOMINMAX) && defined(_MSC_VER)
9 #define NOMINMAX // required to stop windows.h messing up std::min
10 #endif
11 #include <windows.h>
12#endif
13
14#if BS_PLATFORM == BS_PLATFORM_OSX
15 #include <dlfcn.h>
16#endif
17
18namespace bs
19{
20 DynLib::DynLib(String name)
21 :mName(std::move(name))
22 {
23 load();
24 }
25
26 DynLib::~DynLib()
27 {
28 unload();
29 }
30
31 void DynLib::load()
32 {
33 if (mHandle)
34 return;
35
36 mHandle = (DYNLIB_HANDLE)DYNLIB_LOAD(mName.c_str());
37
38 if (!mHandle)
39 {
40 BS_EXCEPT(InternalErrorException,
41 "Could not load dynamic library " + mName + ". System Error: " + dynlibError());
42 }
43 }
44
45 void DynLib::unload()
46 {
47 if (!mHandle)
48 return;
49
50 if (DYNLIB_UNLOAD(mHandle))
51 {
52 BS_EXCEPT(InternalErrorException,
53 "Could not unload dynamic library " + mName + ". System Error: " + dynlibError());
54 }
55
56 mHandle = nullptr;
57 }
58
59 void* DynLib::getSymbol(const String& strName) const
60 {
61 if (!mHandle)
62 return nullptr;
63
64 return (void*)DYNLIB_GETSYM(mHandle, strName.c_str());
65 }
66
67 String DynLib::dynlibError()
68 {
69#if BS_PLATFORM == BS_PLATFORM_WIN32
70 LPVOID lpMsgBuf;
71 FormatMessage(
72 FORMAT_MESSAGE_ALLOCATE_BUFFER |
73 FORMAT_MESSAGE_FROM_SYSTEM |
74 FORMAT_MESSAGE_IGNORE_INSERTS,
75 NULL,
76 GetLastError(),
77 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
78 (LPTSTR)&lpMsgBuf,
79 0,
80 NULL
81 );
82
83 String ret((char*)lpMsgBuf);
84
85 // Free the buffer.
86 LocalFree(lpMsgBuf);
87 return ret;
88#elif BS_PLATFORM == BS_PLATFORM_LINUX || BS_PLATFORM == BS_PLATFORM_OSX
89 return String(dlerror());
90#else
91 return String();
92#endif
93 }
94}
95