Skip to content

Commit

Permalink
refacto: dylib is now dylib::library
Browse files Browse the repository at this point in the history
Signed-off-by: Martin Olivier <[email protected]>
  • Loading branch information
martin-olivier committed Jan 4, 2025
1 parent 8c5f172 commit 13cb8c2
Show file tree
Hide file tree
Showing 3 changed files with 117 additions and 123 deletions.
161 changes: 71 additions & 90 deletions include/dylib.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,26 +22,6 @@
#include <filesystem>
#endif

#if (defined(_WIN32) || defined(_WIN64))
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#define DYLIB_UNDEFINE_LEAN_AND_MEAN
#endif
#ifndef NOMINMAX
#define NOMINMAX
#define DYLIB_UNDEFINE_NOMINMAX
#endif
#include <windows.h>
#ifdef DYLIB_UNDEFINE_LEAN_AND_MEAN
#undef WIN32_LEAN_AND_MEAN
#undef DYLIB_UNDEFINE_LEAN_AND_MEAN
#endif
#ifdef DYLIB_UNDEFINE_NOMINMAX
#undef NOMINMAX
#undef DYLIB_UNDEFINE_NOMINMAX
#endif
#endif

#if (defined(_WIN32) || defined(_WIN64))
#define DYLIB_WIN_MAC_OTHER(win_def, mac_def, other_def) win_def
#define DYLIB_WIN_OTHER(win_def, other_def) win_def
Expand All @@ -53,66 +33,65 @@
#define DYLIB_WIN_OTHER(win_def, other_def) other_def
#endif

/**
* The dylib class can hold a dynamic library instance and interact with it
* by getting its symbols like functions or global variables
*/
class dylib {
public:
struct filename_components {
static constexpr const char *prefix = DYLIB_WIN_OTHER("", "lib");
static constexpr const char *suffix = DYLIB_WIN_MAC_OTHER(".dll", ".dylib", ".so");
};
using native_handle_type = DYLIB_WIN_OTHER(HINSTANCE, void *);
using native_symbol_type = DYLIB_WIN_OTHER(FARPROC, void *);
namespace dylib {

static_assert(std::is_pointer<native_handle_type>::value, "Expecting HINSTANCE to be a pointer");
static_assert(std::is_pointer<native_symbol_type>::value, "Expecting FARPROC to be a pointer");
using native_handle_type = DYLIB_WIN_OTHER(HINSTANCE, void *);
using native_symbol_type = DYLIB_WIN_OTHER(FARPROC, void *);

static constexpr bool add_filename_decorations = true;
static constexpr bool no_filename_decorations = false;
static_assert(std::is_pointer<native_handle_type>::value, "Expecting HINSTANCE to be a pointer");
static_assert(std::is_pointer<native_symbol_type>::value, "Expecting FARPROC to be a pointer");

struct symbol_params {
symbol_params(): demangle(false), loadable(false) {}
bool demangle;
bool loadable;
};
struct symbol_params {
bool demangle{false};
bool loadable{false};
};

/**
* This exception is raised when the library failed to load a dynamic library or a symbol
*
* @param message the error message
*/
class exception : public std::runtime_error {
public:
explicit exception(const std::string &message) : std::runtime_error(message) {}
};
struct filename_components {
static constexpr const char *prefix = DYLIB_WIN_OTHER("", "lib");
static constexpr const char *suffix = DYLIB_WIN_MAC_OTHER(".dll", ".dylib", ".so");
};

/**
* This exception is raised when the library failed to load or encountered symbol resolution issues
*
* @param message the error message
*/
class load_error : public exception {
public:
explicit load_error(const std::string &message) : exception(message) {}
};
/**
* This exception is raised when the library failed to load a dynamic library or a symbol
*
* @param message the error message
*/
class exception : public std::runtime_error {
public:
explicit exception(const std::string &message) : std::runtime_error(message) {}
};

/**
* This exception is raised when the library failed to load a symbol
*
* @param message the error message
*/
class symbol_error : public exception {
public:
explicit symbol_error(const std::string &message) : exception(message) {}
};
/**
* This exception is raised when the library failed to load or encountered symbol resolution issues
*
* @param message the error message
*/
class load_error : public exception {
public:
explicit load_error(const std::string &message) : exception(message) {}
};

dylib(const dylib &) = delete;
dylib &operator=(const dylib &) = delete;
/**
* This exception is raised when the library failed to load a symbol
*
* @param message the error message
*/
class symbol_error : public exception {
public:
explicit symbol_error(const std::string &message) : exception(message) {}
};

/**
* The dylib::library class can hold a dynamic library instance and interact with it
* by getting its symbols like functions or global variables
*/
class library {
public:
library(const library &) = delete;
library &operator=(const library &) = delete;

dylib(dylib &&other) noexcept;
dylib &operator=(dylib &&other) noexcept;
library(library &&other) noexcept;
library &operator=(library &&other) noexcept;

/**
* @brief Loads a dynamic library
Expand All @@ -124,35 +103,35 @@ class dylib {
* @param lib_name the name of the dynamic library to load
* @param decorations add os decorations to the library name
*/
dylib(const char *dir_path, const char *lib_name, bool decorations = add_filename_decorations);
library(const char *dir_path, const char *lib_name, bool decorations = true);

dylib(const std::string &dir_path, const std::string &lib_name, bool decorations = add_filename_decorations)
: dylib(dir_path.c_str(), lib_name.c_str(), decorations) {}
library(const std::string &dir_path, const std::string &lib_name, bool decorations = true)
: library(dir_path.c_str(), lib_name.c_str(), decorations) {}

dylib(const std::string &dir_path, const char *lib_name, bool decorations = add_filename_decorations)
: dylib(dir_path.c_str(), lib_name, decorations) {}
library(const std::string &dir_path, const char *lib_name, bool decorations = true)
: library(dir_path.c_str(), lib_name, decorations) {}

dylib(const char *dir_path, const std::string &lib_name, bool decorations = add_filename_decorations)
: dylib(dir_path, lib_name.c_str(), decorations) {}
library(const char *dir_path, const std::string &lib_name, bool decorations = true)
: library(dir_path, lib_name.c_str(), decorations) {}

explicit dylib(const std::string &lib_name, bool decorations = add_filename_decorations)
: dylib("", lib_name.c_str(), decorations) {}
explicit library(const std::string &lib_name, bool decorations = true)
: library("", lib_name.c_str(), decorations) {}

explicit dylib(const char *lib_name, bool decorations = add_filename_decorations)
: dylib("", lib_name, decorations) {}
explicit library(const char *lib_name, bool decorations = true)
: library("", lib_name, decorations) {}

#ifdef DYLIB_CPP17
explicit dylib(const std::filesystem::path &lib_path)
: dylib("", lib_path.string().c_str(), no_filename_decorations) {}
explicit library(const std::filesystem::path &lib_path)
: library("", lib_path.string().c_str(), false) {}

dylib(const std::filesystem::path &dir_path, const std::string &lib_name, bool decorations = add_filename_decorations)
: dylib(dir_path.string().c_str(), lib_name.c_str(), decorations) {}
library(const std::filesystem::path &dir_path, const std::string &lib_name, bool decorations = true)
: library(dir_path.string().c_str(), lib_name.c_str(), decorations) {}

dylib(const std::filesystem::path &dir_path, const char *lib_name, bool decorations = add_filename_decorations)
: dylib(dir_path.string().c_str(), lib_name, decorations) {}
library(const std::filesystem::path &dir_path, const char *lib_name, bool decorations = true)
: library(dir_path.string().c_str(), lib_name, decorations) {}
#endif

~dylib();
~library();

/**
* Get a symbol from the dynamic library currently loaded in the object
Expand Down Expand Up @@ -260,6 +239,8 @@ class dylib {
#endif
};

} // namespace dylib

#undef DYLIB_WIN_MAC_OTHER
#undef DYLIB_WIN_OTHER
#undef DYLIB_CPP17
41 changes: 27 additions & 14 deletions src/dylib.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,20 @@
#if (defined(_WIN32) || defined(_WIN64))
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#define DYLIB_UNDEFINE_LEAN_AND_MEAN
#endif
#ifndef NOMINMAX
#define NOMINMAX
#define DYLIB_UNDEFINE_NOMINMAX
#endif
#include <windows.h>
#ifdef DYLIB_UNDEFINE_LEAN_AND_MEAN
#undef WIN32_LEAN_AND_MEAN
#else
#include <windows.h>
#undef DYLIB_UNDEFINE_LEAN_AND_MEAN
#endif
#ifdef DYLIB_UNDEFINE_NOMINMAX
#undef NOMINMAX
#undef DYLIB_UNDEFINE_NOMINMAX
#endif
#else
#include <dlfcn.h>
Expand All @@ -25,6 +35,9 @@

#include "dylib.hpp"

using dylib::library;


std::string demangle_symbol(const char *symbol);

#if (defined(_WIN32) || defined(_WIN64))
Expand Down Expand Up @@ -79,14 +92,14 @@ static std::string get_error_description() noexcept {
#endif
}

dylib::dylib(dylib &&other) noexcept {
library::library(library &&other) noexcept {
std::swap(m_handle, other.m_handle);
#if !(defined(_WIN32) || defined(_WIN64))
std::swap(m_fd, other.m_fd);
#endif
}

dylib &dylib::operator=(dylib &&other) noexcept {
library &library::operator=(library &&other) noexcept {
if (this != &other) {
std::swap(m_handle, other.m_handle);
#if !(defined(_WIN32) || defined(_WIN64))
Expand All @@ -96,7 +109,7 @@ dylib &dylib::operator=(dylib &&other) noexcept {
return *this;
}

dylib::dylib(const char *dir_path, const char *lib_name, bool decorations) {
library::library(const char *dir_path, const char *lib_name, bool decorations) {
std::string final_name;
std::string final_dir;
std::string full_path;
Expand Down Expand Up @@ -130,7 +143,7 @@ dylib::dylib(const char *dir_path, const char *lib_name, bool decorations) {
#endif
}

dylib::~dylib() {
library::~library() {
if (m_handle)
close_lib(m_handle);
#if !(defined(_WIN32) || defined(_WIN64))
Expand All @@ -139,7 +152,7 @@ dylib::~dylib() {
#endif
}

dylib::native_symbol_type dylib::get_symbol(const char *symbol_name) const {
dylib::native_symbol_type library::get_symbol(const char *symbol_name) const {
dylib::native_symbol_type symbol;
size_t symbol_name_len;

Expand All @@ -148,7 +161,7 @@ dylib::native_symbol_type dylib::get_symbol(const char *symbol_name) const {
if (symbol_name[0] == '\0')
throw std::invalid_argument("The symbol name to lookup is an empty string");
if (!m_handle)
throw std::logic_error("Attempted to use a moved dylib object, the library handle is null.");
throw std::logic_error("Attempted to use a moved library object.");

symbol_name_len = strlen(symbol_name);

Expand Down Expand Up @@ -183,27 +196,27 @@ dylib::native_symbol_type dylib::get_symbol(const char *symbol_name) const {
return symbol;
}

dylib::native_symbol_type dylib::get_symbol(const std::string &symbol_name) const {
dylib::native_symbol_type library::get_symbol(const std::string &symbol_name) const {
return get_symbol(symbol_name.c_str());
}

bool dylib::has_symbol(const char *symbol_name) const noexcept {
bool library::has_symbol(const char *symbol_name) const noexcept {
if (!m_handle || !symbol_name)
return false;
return locate_symbol(m_handle, symbol_name) != nullptr;
}

bool dylib::has_symbol(const std::string &symbol_name) const noexcept {
bool library::has_symbol(const std::string &symbol_name) const noexcept {
return has_symbol(symbol_name.c_str());
}

dylib::native_handle_type dylib::native_handle() noexcept {
dylib::native_handle_type library::native_handle() noexcept {
return m_handle;
}

std::vector<std::string> dylib::symbols(symbol_params params) const {
std::vector<std::string> library::symbols(symbol_params params) const {
if (!m_handle)
throw std::logic_error("Attempted to use a moved dylib object, the library handle is null.");
throw std::logic_error("Attempted to use a moved library object.");

try {
return get_symbols(
Expand Down
Loading

0 comments on commit 13cb8c2

Please sign in to comment.