1 #pragma once 2 3 4 #include <memory> 5 #include <string> 6 #include <type_traits> 7 #include <utility> 8 #include <uv.h> 9 #include "loop.hpp" 10 #include "underlying_type.hpp" 11 12 13 namespace uvw { 14 15 16 /** 17 * @brief The SharedLib class. 18 * 19 * `uvw` provides cross platform utilities for loading shared libraries and 20 * retrieving symbols from them, by means of the API offered by `libuv`. 21 */ 22 class SharedLib final: public UnderlyingType<SharedLib, uv_lib_t> { 23 public: SharedLib(ConstructorAccess ca,std::shared_ptr<Loop> ref,std::string filename)24 explicit SharedLib(ConstructorAccess ca, std::shared_ptr<Loop> ref, std::string filename) noexcept 25 : UnderlyingType{ca, std::move(ref)} 26 { 27 opened = (0 == uv_dlopen(filename.data(), get())); 28 } 29 ~SharedLib()30 ~SharedLib() noexcept { 31 uv_dlclose(get()); 32 } 33 34 /** 35 * @brief Checks if the library has been correctly opened. 36 * @return True if the library is opened, false otherwise. 37 */ operator bool() const38 explicit operator bool() const noexcept { return opened; } 39 40 /** 41 * @brief Retrieves a data pointer from a dynamic library. 42 * 43 * `F` shall be a valid function type (as an example, `void(int)`).<br/> 44 * It is legal for a symbol to map to `nullptr`. 45 * 46 * @param name The symbol to be retrieved. 47 * @return A valid function pointer in case of success, `nullptr` otherwise. 48 */ 49 template<typename F> sym(std::string name)50 F * sym(std::string name) { 51 static_assert(std::is_function<F>::value, "!"); 52 F *func; 53 auto err = uv_dlsym(get(), name.data(), reinterpret_cast<void**>(&func)); 54 if(err) { func = nullptr; } 55 return func; 56 } 57 58 /** 59 * @brief Returns the last error message, if any. 60 * @return The last error message, if any. 61 */ error() const62 const char * error() const noexcept { 63 return uv_dlerror(get()); 64 } 65 66 private: 67 bool opened; 68 }; 69 70 71 } 72