Skip to content

shared_library.hpp

Alairion edited this page May 8, 2021 · 8 revisions

Shared Library

Not Enough Standards' shared libraries utilities are defined in header <nes/shared_library.hpp>

Description

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.

Synopsis

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;
};

}

Example

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
    }
}
Clone this wiki locally