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 | |
18 | namespace 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 | |