Skip to content

Commit

Permalink
Version 1.8.0 (#10)
Browse files Browse the repository at this point in the history
# Changelog

- feat: `has_symbol` function
- feat: `operator bool()`
- feat: Valgrind CI

# Examples

## has_symbol
```c++
void dylib_symbol_example(const dylib &lib)
{
    if (lib.has_symbol("GetModule"))
        std::cout << "GetModule has been found" << std::endl;
    else
        std::cout << "Could not found GetModule symbol" << std::endl;
}
```

## operator bool()
```c++
void dylib_status_example(const dylib &lib)
{
    if (lib)
        std::cout << "something is curently loaded in the dylib object" << std::endl;
    if (!lib)
        std::cout << "nothing is curently loaded in the dylib object" << std::endl;
}
```
  • Loading branch information
martin-olivier authored Feb 6, 2022
1 parent 625c373 commit 48f3a78
Show file tree
Hide file tree
Showing 4 changed files with 89 additions and 9 deletions.
24 changes: 23 additions & 1 deletion .github/workflows/CI.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name: CI

on: [push]
on: [push, pull_request]

defaults:
run:
Expand Down Expand Up @@ -41,3 +41,25 @@ jobs:
- name: Send Coverage to codecov.io
if: ${{ matrix.os == 'ubuntu-latest' }}
run: bash <(curl -s https://codecov.io/bash)

memory_check:
name: memory check
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v2

- name: Update Packages
run: sudo apt update

- name: Install Valgrind
run: sudo apt install -y valgrind

- name: Generate Tests Build File
run: cmake . -B build -DBUILD_TESTS=ON -DCMAKE_BUILD_TYPE=Debug

- name: Build Unit Tests
run: cmake --build build

- name: Run Unit Tests with Valgrind
run: valgrind --leak-check=full --show-leak-kinds=all --error-exitcode=1 ./unit_tests
9 changes: 6 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Dylib - Dynamic Library Loader for C++
[![Dylib](https://img.shields.io/badge/Dylib-v1.7.1-blue.svg)](https://github.com/martin-olivier/dylib/releases/tag/v1.7.1)
[![Dylib](https://img.shields.io/badge/Dylib-v1.8.0-blue.svg)](https://github.com/martin-olivier/dylib/releases/tag/v1.8.0)
[![MIT license](https://img.shields.io/badge/License-MIT-orange.svg)](https://github.com/martin-olivier/dylib/blob/main/LICENSE)
[![CPP Version](https://img.shields.io/badge/C++-11_and_above-darkgreen.svg)](https://isocpp.org/)

Expand All @@ -10,7 +10,7 @@
[![workflow](https://github.com/martin-olivier/dylib/actions/workflows/CI.yml/badge.svg)](https://github.com/martin-olivier/dylib/actions/workflows/CI.yml)
[![codecov](https://codecov.io/gh/martin-olivier/dylib/branch/main/graph/badge.svg?token=4V6A9B7PII)](https://codecov.io/gh/martin-olivier/dylib)

[![GitHub download](https://img.shields.io/github/downloads/martin-olivier/dylib/total?style=for-the-badge)](https://github.com/martin-olivier/dylib/releases/download/v1.7.1/dylib.hpp)
[![GitHub download](https://img.shields.io/github/downloads/martin-olivier/dylib/total?style=for-the-badge)](https://github.com/martin-olivier/dylib/releases/download/v1.8.0/dylib.hpp)

The goal of this C++ Library is to load dynamic libraries (.so, .dll, .dylib) and access its functions and global variables at runtime.

Expand All @@ -19,7 +19,7 @@ Works on `Linux`, `Windows`, `MacOS`

# Installation

Click [HERE](https://github.com/martin-olivier/dylib/releases/download/v1.7.1/dylib.hpp) to download the dylib header file
Click [HERE](https://github.com/martin-olivier/dylib/releases/download/v1.8.0/dylib.hpp) to download the dylib header file
`⭐ Don't forget to put a star if you like the project!`

# Documentation
Expand Down Expand Up @@ -63,6 +63,9 @@ lib.close();
## Get a Function or a Variable
`has_symbol`
Check if a symbol exists in the currently loaded dynamic library.
`get_function`
Get a function from the dynamic library currently loaded in the object.
Expand Down
40 changes: 35 additions & 5 deletions dylib.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
* \file dylib.hpp
* \brief Cross-platform Dynamic Library Loader
* \author Martin Olivier
* \version 1.7.1
* \version 1.8.0
*
* MIT License
* Copyright (c) 2022 Martin Olivier
Expand Down Expand Up @@ -93,9 +93,9 @@ class dylib
return msg;
return msg + '\n' + err;
}
static std::string get_missing_handle_error(const std::string &name)
static std::string get_missing_handle_error(const std::string &symbol_name)
{
return "dylib: could not get symbol \"" + name + "\", no dynamic library loaded";
return "dylib: could not get symbol \"" + symbol_name + "\", no dynamic library currently loaded";
}

public:
Expand Down Expand Up @@ -229,7 +229,7 @@ class dylib
* it must be the same pattern as the template of std::function
* @param name the symbol name of the function to get from the dynamic library
*
* @returns std::function<T> that contains the function
* @return std::function<T> that contains the function
*/
template<typename T>
std::function<T> get_function(const char *name) const
Expand All @@ -256,7 +256,7 @@ class dylib
* @param T type of the global variable
* @param name the name of the global variable to get from the dynamic library
*
* @returns global variable of type <T>
* @return global variable of type <T>
*/
template<typename T>
T &get_variable(const char *name) const
Expand All @@ -277,6 +277,36 @@ class dylib
return get_variable<T>(name.c_str());
}

/**
* Check if a symbol exists in the currently loaded dynamic library.
* This method will return false if no dynamic library is currently loaded or if the symbol equals nullptr
*
* @param symbol the symbol name to look for
*
* @return true if the symbol exists in the dynamic library, false otherwise
*/
bool has_symbol(const char *symbol) const noexcept
{
if (!m_handle)
return false;
if (!symbol)
return false;
return get_symbol(symbol) != nullptr;
}

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

/**
* @return true if a dynamic library is currently loaded in the object, false otherwise
*/
operator bool() const noexcept
{
return m_handle != nullptr;
}

/**
* Close the dynamic library currently loaded in the object.
* This function will be automatically called by the class destructor
Expand Down
25 changes: 25 additions & 0 deletions tests/tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,31 @@ TEST(std_move, basic_test)
}
}

TEST(has_symbol, basic_test)
{
dylib lib;
EXPECT_FALSE(lib.has_symbol(nullptr));
EXPECT_FALSE(lib.has_symbol("pi_value"));
lib.open("./dynamic_lib", dylib::extension);
EXPECT_TRUE(lib.has_symbol("pi_value"));
EXPECT_FALSE(lib.has_symbol("bad_symbol"));
lib.close();
EXPECT_FALSE(lib.has_symbol("pi_value"));
}

TEST(operator_bool, basic_test)
{
dylib lib;
EXPECT_FALSE(lib);
EXPECT_TRUE(!lib);
lib.open("./dynamic_lib", dylib::extension);
EXPECT_TRUE(lib);
EXPECT_FALSE(!lib);
lib.close();
EXPECT_TRUE(!lib);
EXPECT_FALSE(lib);
}

int main(int ac, char **av)
{
testing::InitGoogleTest(&ac, av);
Expand Down

0 comments on commit 48f3a78

Please sign in to comment.