-
Notifications
You must be signed in to change notification settings - Fork 7
shared_library.hpp
Not Enough Standards' shared libraries utilities are defined in header <nes/shared_library.hpp>
Shared libraries sometimes need to be loaded dynamically, e.g. Vulkan loader or Windows' kernel functions. To do this, you have to use system specific functions. But loading libraries is a redundant feature, most systems only provide two functions, one to load a shared library object (.so, .dll, ...) and one to resolve symbols within it. nes::shared_library
provide this two functions, plus a way to load current binary as a shared library.
nes::load_current
is a disambiguation tag of type nes::load_current_t
that can be passed to nes::shared_library
constructor to load current binary as a shared library.
nes::shared_library
is the main class of this header. It represents a shared library object. A shared library is loaded using its path.
namespace nes
{
struct load_current_t{};
static constexpr load_current_t load_current{};
class shared_library
{
public:
using native_handle_type = /*implementation-defined*/;
public:
constexpr shared_library() noexcept = default;
explicit shared_library(load_current_t);
explicit shared_library(const std::string& path);
~shared_library();
shared_library(const shared_library&) = delete;
shared_library& operator=(const shared_library&) = delete;
shared_library(shared_library&& other) noexcept;
shared_library& operator=(shared_library&& other) noexcept;
template<typename Func, typename = std::enable_if_t<std::is_pointer_v<Func> && std::is_function_v<std::remove_pointer_t<Func>>>>
Func load(const std::string& symbol) const noexcept;
template<typename Func, typename = std::enable_if_t<std::is_function_v<Func>>>
Func* load(const std::string& symbol) const noexcept;
native_handle_type native_handle() const noexcept;
};
}
Here is an example in which we load the Vulkan library, for Windows or Linux:
#include <nes/shared_library.hpp>
#include <vulkan.h>
#if defined(VK_USE_PLATFORM_WIN32_KHR) //Windows
constexpr const char* vulkan_path = "vulkan-1.dll";
#elif defined(VK_USE_PLATFORM_XCB_KHR) || defined(VK_USE_PLATFORM_XLIB_KHR) //Linux
constexpr const char* vulkan_path = "libvulkan.so";
#endif
int main()
{
nes::shared_library vulkan_loader{vulkan_path};
auto vk_get_instance_proc_addr{vulkan_loader.load<PFN_vkGetInstanceProcAddr>("vkGetInstanceProcAddr")};
if(vulkan_get_instance_proc_addr)
{
//Do something with the function you loaded
}
}