Mercurial > code
changeset 558:5725e2d2ab4c
Dynlib: add overload that does not throw
author | David Demelier <markand@malikania.fr> |
---|---|
date | Sun, 19 Jun 2016 16:52:32 +0200 |
parents | a8b5e0bb59f7 |
children | 5554ba5dc1dc |
files | modules/dynlib/dynlib.hpp modules/dynlib/test/main.cpp |
diffstat | 2 files changed, 29 insertions(+), 22 deletions(-) [+] |
line wrap: on
line diff
--- a/modules/dynlib/dynlib.hpp Sun Jun 19 16:41:10 2016 +0200 +++ b/modules/dynlib/dynlib.hpp Sun Jun 19 16:52:32 2016 +0200 @@ -118,8 +118,8 @@ * try { * Dynlib dso("./plugin" DYNLIB_SUFFIX); * - * dso.sym<PluginLoad>("plugin_load")(); - * dso.sym<PluginUnload>("plugin_unload")(); + * dso.require<PluginLoad>("plugin_load")(); + * dso.require<PluginUnload>("plugin_unload")(); * } catch (const std::exception &ex) { * std::cerr << ex.what() << std::endl; * } @@ -254,15 +254,30 @@ /** * Get a symbol from the library. * - * On some platforms the symbol must be manually exported. + * \param name the symbol + * \return the symbol + * \throw std::out_of_range on error + * \see DYNLIB_EXPORT + */ + template <typename T> + inline T require(const std::string &name) + { + auto sym = get<T>(name); + + if (!sym) + throw std::out_of_range(name + ": symbol not found"); + + return sym; + } + + /** + * Get a symbol from the library or return nullptr if not found. * * \param name the symbol * \return the symbol - * \throw std::runtime_error on error - * \see DYNLIB_EXPORT */ template <typename T> - T sym(const std::string &name); + T get(const std::string &name) noexcept; }; #if defined(_WIN32) @@ -287,14 +302,9 @@ } template <typename T> -T Dynlib::sym(const std::string &name) +inline T Dynlib::get(const std::string &name) noexcept { - Sym sym = GetProcAddress(m_handle, name.c_str()); - - if (sym == nullptr) - throw std::runtime_error(error()); - - return reinterpret_cast<T>(sym); + return reinterpret_cast<T>(GetProcAddress(m_handle, name.c_str())); } #else @@ -319,14 +329,9 @@ } template <typename T> -T Dynlib::sym(const std::string &name) +inline T Dynlib::get(const std::string &name) noexcept { - Sym sym = dlsym(m_handle, name.c_str()); - - if (sym == nullptr) - throw std::runtime_error(dlerror()); - - return reinterpret_cast<T>(sym); + return reinterpret_cast<T>(dlsym(m_handle, name.c_str())); } #endif
--- a/modules/dynlib/test/main.cpp Sun Jun 19 16:41:10 2016 +0200 +++ b/modules/dynlib/test/main.cpp Sun Jun 19 16:52:32 2016 +0200 @@ -28,7 +28,7 @@ { try { Dynlib library(PLUGIN); - Initialize init = library.sym<Initialize>("initialize"); + Initialize init = library.require<Initialize>("initialize"); std::string expected("Hello World"); std::string result; @@ -36,6 +36,7 @@ init(result); ASSERT_EQ(expected, result); + ASSERT_TRUE(library.get<Initialize>("initialize")); } catch (const std::runtime_error &error) { FAIL() << error.what(); } @@ -45,7 +46,8 @@ { Dynlib library(PLUGIN); - ASSERT_THROW(library.sym<Initialize>("initialize_typo"), std::runtime_error); + ASSERT_THROW(library.require<Initialize>("initialize_typo"), std::out_of_range); + ASSERT_FALSE(library.get<Initialize>("initialize_type")); } int main(int argc, char **argv)