diff --git a/src/uvw.hpp b/src/uvw.hpp index 45073681..e862dc79 100644 --- a/src/uvw.hpp +++ b/src/uvw.hpp @@ -4,6 +4,7 @@ #include "uvw/fs.hpp" #include "uvw/fs_poll.hpp" #include "uvw/idle.hpp" +#include "uvw/lib.hpp" #include "uvw/loop.hpp" #include "uvw/pipe.hpp" #include "uvw/poll.hpp" diff --git a/src/uvw/lib.hpp b/src/uvw/lib.hpp new file mode 100644 index 00000000..62a2442d --- /dev/null +++ b/src/uvw/lib.hpp @@ -0,0 +1,71 @@ +#pragma once + + +#include +#include +#include +#include +#include "resource.hpp" + + +namespace uvw { + + +namespace details { + + +template struct IsFunc: std::false_type { }; +template struct IsFunc: std::true_type { }; + + +} + + +class SharedLib final { + explicit SharedLib(std::shared_ptr ref, std::string filename) noexcept + : pLoop{std::move(ref)}, lib{} + { + opened = (0 == uv_dlopen(filename.data(), &lib)); + } + +public: + template + static std::shared_ptr create(Args&&... args) noexcept { + return std::shared_ptr{new SharedLib{std::forward(args)...}}; + } + + SharedLib(const SharedLib &) = delete; + SharedLib(SharedLib &&) = delete; + + ~SharedLib() noexcept { + uv_dlclose(&lib); + } + + SharedLib& operator=(const SharedLib &) = delete; + SharedLib& operator=(SharedLib &&) = delete; + + explicit operator bool() const noexcept { return !opened; } + + template + F * sym(std::string name) { + static_assert(details::IsFunc::value, "!"); + F *func; + auto err = uv_dlsym(&lib, name.data(), reinterpret_cast(&func)); + if(err) { func = nullptr; } + return func; + } + + const char * error() const noexcept { + return uv_dlerror(&lib); + } + + Loop& loop() const noexcept { return *pLoop; } + +private: + std::shared_ptr pLoop; + uv_lib_t lib; + bool opened; +}; + + +}