# HG changeset patch # User David Demelier # Date 1466347952 -7200 # Node ID 5725e2d2ab4c38cfceb129ea8c629c277554d811 # Parent a8b5e0bb59f7642ba3c05b958e501e944f4e18e6 Dynlib: add overload that does not throw diff -r a8b5e0bb59f7 -r 5725e2d2ab4c modules/dynlib/dynlib.hpp --- 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("plugin_load")(); - * dso.sym("plugin_unload")(); + * dso.require("plugin_load")(); + * dso.require("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 + inline T require(const std::string &name) + { + auto sym = get(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 - T sym(const std::string &name); + T get(const std::string &name) noexcept; }; #if defined(_WIN32) @@ -287,14 +302,9 @@ } template -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(sym); + return reinterpret_cast(GetProcAddress(m_handle, name.c_str())); } #else @@ -319,14 +329,9 @@ } template -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(sym); + return reinterpret_cast(dlsym(m_handle, name.c_str())); } #endif diff -r a8b5e0bb59f7 -r 5725e2d2ab4c modules/dynlib/test/main.cpp --- 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 init = library.require("initialize"); std::string expected("Hello World"); std::string result; @@ -36,6 +36,7 @@ init(result); ASSERT_EQ(expected, result); + ASSERT_TRUE(library.get("initialize")); } catch (const std::runtime_error &error) { FAIL() << error.what(); } @@ -45,7 +46,8 @@ { Dynlib library(PLUGIN); - ASSERT_THROW(library.sym("initialize_typo"), std::runtime_error); + ASSERT_THROW(library.require("initialize_typo"), std::out_of_range); + ASSERT_FALSE(library.get("initialize_type")); } int main(int argc, char **argv)