|
- //
- // ██████ ██ ██ ██████ ██████
- // ██ ██ ██ ██ ██ ██ ** Classy Header-Only Classes **
- // ██ ███████ ██ ██ ██
- // ██ ██ ██ ██ ██ ██ https://github.com/Tracktion/choc
- // ██████ ██ ██ ██████ ██████
- //
- // CHOC is (C)2022 Tracktion Corporation, and is offered under the terms of the ISC license:
- //
- // Permission to use, copy, modify, and/or distribute this software for any purpose with or
- // without fee is hereby granted, provided that the above copyright notice and this permission
- // notice appear in all copies. THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
- // WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- // AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR
- // CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
- // WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
- // CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
- #ifndef CHOC_DYNAMIC_LIBRARY_HEADER_INCLUDED
- #define CHOC_DYNAMIC_LIBRARY_HEADER_INCLUDED
-
- #include <string>
-
- START_NAMESPACE_DISTRHO
-
- //==============================================================================
- /**
- A minimal cross-platform loader for .dll/.so files.
- */
- struct DynamicLibrary
- {
- DynamicLibrary() = default;
-
- /// Attempts to load a library with the given name or path.
- DynamicLibrary (std::string_view library);
-
- DynamicLibrary (const DynamicLibrary&) = delete;
- DynamicLibrary& operator= (const DynamicLibrary&) = delete;
- DynamicLibrary (DynamicLibrary&&);
- DynamicLibrary& operator= (DynamicLibrary&&);
-
- /// On destruction, this object releases the library that was loaded
- ~DynamicLibrary();
-
- /// Returns a pointer to the function with this name, or nullptr if not found.
- void* findFunction (std::string_view functionName);
-
- /// Returns true if the library was successfully loaded
- operator bool() const noexcept { return handle != nullptr; }
-
- /// Releases any handle that this object is holding
- void close();
-
- /// platform-specific handle. Will be nullptr if not loaded
- void* handle = nullptr;
- };
-
-
-
- //==============================================================================
- // _ _ _ _
- // __| | ___ | |_ __ _ (_)| | ___
- // / _` | / _ \| __| / _` || || |/ __|
- // | (_| || __/| |_ | (_| || || |\__ \ _ _ _
- // \__,_| \___| \__| \__,_||_||_||___/(_)(_)(_)
- //
- // Code beyond this point is implementation detail...
- //
- //==============================================================================
-
- inline DynamicLibrary::~DynamicLibrary()
- {
- close();
- }
-
- inline DynamicLibrary::DynamicLibrary (DynamicLibrary&& other) : handle (other.handle)
- {
- other.handle = nullptr;
- }
-
- inline DynamicLibrary& DynamicLibrary::operator= (DynamicLibrary&& other)
- {
- close();
- handle = other.handle;
- other.handle = nullptr;
- return *this;
- }
-
- //==============================================================================
- namespace win32_defs
- {
- #if ! (defined (_WINDOWS_) || defined (_APISETLIBLOADER_)) // only use these local definitions if windows.h isn't already included
- using CHOC_HMODULE = void*;
- #ifdef _MSC_VER
- extern "C" CHOC_HMODULE __stdcall choc_LoadLibraryA (const char*);
- extern "C" int __stdcall choc_FreeLibrary (CHOC_HMODULE);
- extern "C" void* __stdcall choc_GetProcAddress (CHOC_HMODULE, const char*);
- #pragma comment(linker,"/alternatename:choc_LoadLibraryA=LoadLibraryA")
- #pragma comment(linker,"/alternatename:choc_FreeLibrary=FreeLibrary")
- #pragma comment(linker,"/alternatename:choc_GetProcAddress=GetProcAddress")
- static inline CHOC_HMODULE LoadLibraryA (const char* l) { return choc_LoadLibraryA (l); }
- static inline int FreeLibrary (CHOC_HMODULE m) { return choc_FreeLibrary (m); }
- static inline void* GetProcAddress (CHOC_HMODULE m, const char* f) { return choc_GetProcAddress (m, f); }
- #else
- extern "C" __declspec(dllimport) CHOC_HMODULE __stdcall LoadLibraryA (const char*);
- extern "C" __declspec(dllimport) int __stdcall FreeLibrary (CHOC_HMODULE);
- extern "C" __declspec(dllimport) void* __stdcall GetProcAddress (CHOC_HMODULE, const char*);
- #endif
- #else
- using CHOC_HMODULE = HMODULE;
- static inline CHOC_HMODULE LoadLibraryA (const char* l) { return ::LoadLibraryA (l); }
- static inline int FreeLibrary (CHOC_HMODULE m) { return ::FreeLibrary (m); }
- static inline void* GetProcAddress (CHOC_HMODULE m, const char* f) { return (void*) ::GetProcAddress (m, f); }
- #endif
- }
-
- inline DynamicLibrary::DynamicLibrary (std::string_view library)
- {
- handle = (void*) win32_defs::LoadLibraryA (std::string (library).c_str());
- }
-
- inline void DynamicLibrary::close()
- {
- if (handle != nullptr)
- {
- win32_defs::FreeLibrary ((win32_defs::CHOC_HMODULE) handle);
- handle = nullptr;
- }
- }
-
- inline void* DynamicLibrary::findFunction (std::string_view name)
- {
- if (handle != nullptr)
- return (void*) win32_defs::GetProcAddress ((win32_defs::CHOC_HMODULE) handle, std::string (name).c_str());
-
- return {};
- }
-
- END_NAMESPACE_DISTRHO
-
- #endif // CHOC_DYNAMIC_LIBRARY_HEADER_INCLUDED
|