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 | #pragma once |
4 | |
5 | #include "Prerequisites/BsPrerequisitesUtil.h" |
6 | |
7 | #if BS_PLATFORM == BS_PLATFORM_WIN32 |
8 | struct HINSTANCE__; |
9 | typedef struct HINSTANCE__* hInstance; |
10 | #endif |
11 | |
12 | namespace bs |
13 | { |
14 | /** @addtogroup General |
15 | * @{ |
16 | */ |
17 | |
18 | #if BS_PLATFORM == BS_PLATFORM_WIN32 |
19 | # define DYNLIB_HANDLE hInstance |
20 | # define DYNLIB_LOAD( a ) LoadLibraryEx( a, NULL, LOAD_WITH_ALTERED_SEARCH_PATH ) |
21 | # define DYNLIB_GETSYM( a, b ) GetProcAddress( a, b ) |
22 | # define DYNLIB_UNLOAD( a ) !FreeLibrary( a ) |
23 | |
24 | #elif BS_PLATFORM == BS_PLATFORM_LINUX || BS_PLATFORM == BS_PLATFORM_OSX |
25 | # define DYNLIB_HANDLE void* |
26 | # define DYNLIB_LOAD( a ) dlopen( a, RTLD_LAZY | RTLD_GLOBAL) |
27 | # define DYNLIB_GETSYM( a, b ) dlsym( a, b ) |
28 | # define DYNLIB_UNLOAD( a ) dlclose( a ) |
29 | |
30 | #endif |
31 | |
32 | /** Class that holds data about a dynamic library. */ |
33 | class BS_UTILITY_EXPORT DynLib final |
34 | { |
35 | public: |
36 | /** Platform-specific file extension for a dynamic library (e.g. "dll"). */ |
37 | #if BS_PLATFORM == BS_PLATFORM_LINUX |
38 | static constexpr const char* EXTENSION = "so" ; |
39 | #elif BS_PLATFORM == BS_PLATFORM_OSX |
40 | static constexpr const char* EXTENSION = "dylib" ; |
41 | #elif BS_PLATFORM == BS_PLATFORM_WIN32 |
42 | static constexpr const char* EXTENSION = "dll" ; |
43 | #else |
44 | #error Unhandled platform |
45 | #endif |
46 | |
47 | /** Platform-specific name suffix for a dynamic library (e.g. "lib" on Unix) */ |
48 | #if BS_PLATFORM == BS_PLATFORM_LINUX |
49 | static constexpr const char* PREFIX = "lib" ; |
50 | #elif BS_PLATFORM == BS_PLATFORM_OSX |
51 | static constexpr const char* PREFIX = "lib" ; |
52 | #elif BS_PLATFORM == BS_PLATFORM_WIN32 |
53 | static constexpr const char* PREFIX = nullptr; |
54 | #else |
55 | #error Unhandled platform |
56 | #endif |
57 | |
58 | /** Constructs the dynamic library object and loads the library with the specified name. */ |
59 | DynLib(String name); |
60 | ~DynLib(); |
61 | |
62 | /** Loads the library. Does nothing if library is already loaded. */ |
63 | void load(); |
64 | |
65 | /** Unloads the library. Does nothing if library is not loaded. */ |
66 | void unload(); |
67 | |
68 | /** Get the name of the library. */ |
69 | const String& getName() const { return mName; } |
70 | |
71 | /** |
72 | * Returns the address of the given symbol from the loaded library. |
73 | * |
74 | * @param[in] strName The name of the symbol to search for. |
75 | * @return If the function succeeds, the returned value is a handle to the symbol. Otherwise null. |
76 | */ |
77 | void* getSymbol(const String& strName) const; |
78 | |
79 | protected: |
80 | friend class DynLibManager; |
81 | |
82 | /** Gets the last loading error. */ |
83 | String dynlibError(); |
84 | |
85 | protected: |
86 | const String mName; |
87 | DYNLIB_HANDLE mHandle = nullptr; |
88 | }; |
89 | |
90 | /** @} */ |
91 | } |
92 | |