diff --git a/source/util/util-library.cpp b/source/util/util-library.cpp index dfd8b7de..3ee65db7 100644 --- a/source/util/util-library.cpp +++ b/source/util/util-library.cpp @@ -21,7 +21,7 @@ #endif #include "warning-enable.hpp" -streamfx::util::library::library(std::filesystem::path file) : _library(nullptr) +streamfx::util::library::library(std::filesystem::path file) : _library(nullptr), _owner(true) { #if defined(ST_WINDOWS) SetLastError(ERROR_SUCCESS); @@ -57,13 +57,17 @@ streamfx::util::library::library(std::filesystem::path file) : _library(nullptr) #endif } +streamfx::util::library::library(obs_module_t* library) : _library(obs_get_module_lib(library)), _owner(false) {} + streamfx::util::library::~library() { + if (_owner) { #if defined(ST_WINDOWS) - FreeLibrary(reinterpret_cast(_library)); + FreeLibrary(reinterpret_cast(_library)); #elif defined(ST_UNIX) - dlclose(_library); + dlclose(_library); #endif + } } void* streamfx::util::library::load_symbol(std::string_view name) @@ -96,3 +100,24 @@ std::shared_ptr<::streamfx::util::library> streamfx::util::library::load(std::st { return load(std::filesystem::u8path(name)); } + +std::shared_ptr<::streamfx::util::library> streamfx::util::library::load(obs_module_t* instance) +{ + // Get an absolute path to the module. + auto path = std::filesystem::absolute(std::filesystem::u8path(obs_get_module_binary_path(instance))); + + // Find by absolute path. + auto kv = libraries.find(path.u8string()); + if (kv != libraries.end()) { + if (auto ptr = kv->second.lock(); ptr) { + return ptr; + } + libraries.erase(kv); + } + + // If neither matches, add it to the registry. + std::shared_ptr<::streamfx::util::library> ptr{new ::streamfx::util::library(instance)}; + libraries.emplace(path.u8string(), ptr); + + return ptr; +} diff --git a/source/util/util-library.hpp b/source/util/util-library.hpp index c52beedb..5e8b9b8b 100644 --- a/source/util/util-library.hpp +++ b/source/util/util-library.hpp @@ -7,20 +7,27 @@ #include #include #include + +#include #include "warning-enable.hpp" namespace streamfx::util { class library { void* _library; + bool _owner; public: library(std::filesystem::path file); + library(obs_module_t* library); ~library(); void* load_symbol(std::string_view name); + public: static std::shared_ptr<::streamfx::util::library> load(std::filesystem::path file); static std::shared_ptr<::streamfx::util::library> load(std::string_view name); + + static std::shared_ptr<::streamfx::util::library> load(obs_module_t* instance); }; } // namespace streamfx::util