// // Yet Another POD-Bot, based on PODBot by Markus Klinge ("CountFloyd"). // Copyright (c) YaPB Development Team. // // This software is licensed under the BSD-style license. // Additional exceptions apply. For full license details, see LICENSE.txt or visit: // https://yapb.ru/license // #pragma once #include #include #if defined (CR_LINUX) || defined (CR_OSX) # include # include # include # include # include #endif CR_NAMESPACE_BEGIN // handling dynamic library loading class SharedLibrary final : public DenyCopying { private: void *m_handle = nullptr; public: explicit SharedLibrary () = default; SharedLibrary (const String &file) { if (file.empty ()) { return; } load (file); } ~SharedLibrary () { unload (); } public: bool load (const String &file) noexcept { if (*this) { unload (); } #if defined (CR_WINDOWS) m_handle = LoadLibraryA (file.chars ()); #else m_handle = dlopen (file.chars (), RTLD_NOW); #endif return m_handle != nullptr; } bool locate (void *address) { #if defined (CR_WINDOWS) MEMORY_BASIC_INFORMATION mbi; if (!VirtualQuery (address, &mbi, sizeof (mbi))) { return false; } if (mbi.State != MEM_COMMIT) { return false; } m_handle = reinterpret_cast (mbi.AllocationBase); #else Dl_info dli; memset (&dli, 0, sizeof (dli)); if (dladdr (address, &dli)) { return load (dli.dli_fname); } #endif return m_handle != nullptr; } void unload () noexcept { if (!*this) { return; } #if defined (CR_WINDOWS) FreeLibrary (static_cast (m_handle)); #else dlclose (m_handle); #endif m_handle = nullptr; } template R resolve (const char *function) const { if (!*this) { return nullptr; } return reinterpret_cast ( #if defined (CR_WINDOWS) GetProcAddress (static_cast (m_handle), function) #else dlsym (m_handle, function) #endif ); } void *handle () const { return m_handle; } public: explicit operator bool () const { return m_handle != nullptr; } }; CR_NAMESPACE_END