util/library: Allow loading of obs_module_t

Allows us to pass an obs_module_t into util::library::load() for cleaner code. This requires an additional flag so we don't unload a module that is still in use by libOBS.
This commit is contained in:
Michael Fabian 'Xaymar' Dirks 2023-03-09 15:14:12 +01:00
parent 10921f56e3
commit 54859e9f14
2 changed files with 35 additions and 3 deletions

View file

@ -21,7 +21,7 @@
#endif #endif
#include "warning-enable.hpp" #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) #if defined(ST_WINDOWS)
SetLastError(ERROR_SUCCESS); SetLastError(ERROR_SUCCESS);
@ -57,13 +57,17 @@ streamfx::util::library::library(std::filesystem::path file) : _library(nullptr)
#endif #endif
} }
streamfx::util::library::library(obs_module_t* library) : _library(obs_get_module_lib(library)), _owner(false) {}
streamfx::util::library::~library() streamfx::util::library::~library()
{ {
if (_owner) {
#if defined(ST_WINDOWS) #if defined(ST_WINDOWS)
FreeLibrary(reinterpret_cast<HMODULE>(_library)); FreeLibrary(reinterpret_cast<HMODULE>(_library));
#elif defined(ST_UNIX) #elif defined(ST_UNIX)
dlclose(_library); dlclose(_library);
#endif #endif
}
} }
void* streamfx::util::library::load_symbol(std::string_view name) 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)); 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;
}

View file

@ -7,20 +7,27 @@
#include <filesystem> #include <filesystem>
#include <memory> #include <memory>
#include <string_view> #include <string_view>
#include <obs.h>
#include "warning-enable.hpp" #include "warning-enable.hpp"
namespace streamfx::util { namespace streamfx::util {
class library { class library {
void* _library; void* _library;
bool _owner;
public: public:
library(std::filesystem::path file); library(std::filesystem::path file);
library(obs_module_t* library);
~library(); ~library();
void* load_symbol(std::string_view name); 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::filesystem::path file);
static std::shared_ptr<::streamfx::util::library> load(std::string_view name); 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 } // namespace streamfx::util