Edit: /usr/include/boost/dll/import_mangled.hpp (11548B)
// Copyright 2015-2018 Klemens D. Morgenstern
// Copyright 2019-2020 Antony Polukhin
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt
// or copy at http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_DLL_IMPORT_MANGLED_HPP_
#define BOOST_DLL_IMPORT_MANGLED_HPP_
/// \file boost/dll/import_mangled.hpp
/// \warning Extremely experimental! Requires C++11! Will change in next version of Boost! boost/dll/import_mangled.hpp is not included in boost/dll.hpp
/// \brief Contains the boost::dll::experimental::import_mangled function for importing mangled symbols.
#include
#if (__cplusplus < 201103L) && (!defined(_MSVC_LANG) || _MSVC_LANG < 201103L)
# error This file requires C++11 at least!
#endif
#include
#include
#include
#include
#include
#include
#include
#include
#ifdef BOOST_HAS_PRAGMA_ONCE
# pragma once
#endif
namespace boost { namespace dll { namespace experimental {
namespace detail
{
template
class mangled_library_function {
// Copying of `boost::dll::shared_library` is very expensive, so we use a `shared_ptr` to make it faster.
boost::shared_ptr lib_;
function_tuple f_;
public:
constexpr mangled_library_function(const boost::shared_ptr& lib, Ts*... func_ptr) BOOST_NOEXCEPT
: lib_(lib)
, f_(func_ptr...)
{}
// Compilation error at this point means that imported function
// was called with unmatching parameters.
//
// Example:
// auto f = dll::import_mangled("function", "lib.so");
// f("Hello"); // error: invalid conversion from 'const char*' to 'int'
// f(1, 2); // error: too many arguments to function
// f(); // error: too few arguments to function
template
auto operator()(Args&&... args) const
-> decltype( f_(static_cast(args)...) )
{
return f_(static_cast(args)...);
}
};
template
class mangled_library_mem_fn;
template
class mangled_library_mem_fn> {
// Copying of `boost::dll::shared_library` is very expensive, so we use a `shared_ptr` to make it faster.
typedef mem_fn_tuple call_tuple_t;
boost::shared_ptr lib_;
call_tuple_t f_;
public:
constexpr mangled_library_mem_fn(const boost::shared_ptr& lib, typename Ts::mem_fn... func_ptr) BOOST_NOEXCEPT
: lib_(lib)
, f_(func_ptr...)
{}
template
auto operator()(ClassIn *cl, Args&&... args) const
-> decltype( f_(cl, static_cast(args)...) )
{
return f_(cl, static_cast(args)...);
}
};
// simple enough to be here
template struct is_variable : boost::false_type {};
template struct is_variable> : boost::is_object {};
template ::value,
bool isMemFn = is_mem_fn_seq ::value,
bool isVariable = is_variable ::value>
struct mangled_import_type;
template
struct mangled_import_type, true,false,false> //is function
{
typedef boost::dll::experimental::detail::mangled_library_function type;
static type make(
const boost::dll::experimental::smart_library& p,
const std::string& name)
{
return type(
boost::make_shared(p.shared_lib()),
boost::addressof(p.get_function(name))...);
}
};
template
struct mangled_import_type, false, true, false> //is member-function
{
typedef typename boost::dll::experimental::detail::make_mem_fn_seq::type actual_sequence;
typedef typename boost::dll::experimental::detail::mangled_library_mem_fn type;
template
static type make_impl(
const boost::dll::experimental::smart_library& p,
const std::string & name,
sequence * )
{
return type(boost::make_shared(p.shared_lib()),
p.get_mem_fn(name)...);
}
static type make(
const boost::dll::experimental::smart_library& p,
const std::string& name)
{
return make_impl(p, name, static_cast(nullptr));
}
};
template
struct mangled_import_type, false, false, true> //is variable
{
typedef boost::shared_ptr type;
static type make(
const boost::dll::experimental::smart_library& p,
const std::string& name)
{
return type(
boost::make_shared(p.shared_lib()),
boost::addressof(p.get_variable(name)));
}
};
} // namespace detail
#ifndef BOOST_DLL_DOXYGEN
# define BOOST_DLL_MANGLED_IMPORT_RESULT_TYPE inline typename \
boost::dll::experimental::detail::mangled_import_type>::type
#endif
/*
* Variants:
* import_mangled("Stuff");
* import_mangled("Function");
* import mangled("Function");
*/
/*!
* Returns callable object or boost::shared_ptr that holds the symbol imported
* from the loaded library. Returned value refcounts usage
* of the loaded shared library, so that it won't get unload until all copies of return value
* are not destroyed.
*
* For importing symbols by \b alias names use \forcedlink{import_alias} method.
*
* \b Examples:
*
* \code
* boost::function f = import_mangled("test_lib.so", "integer_func_name");
*
* auto f_cpp11 = import_mangled("test_lib.so", "integer_func_name");
* \endcode
*
* \code
* boost::shared_ptr i = import_mangled("test_lib.so", "integer_name");
* \endcode
*
* Additionally you can also import overloaded symbols, including member-functions.
*
* \code
* auto fp = import_mangled("test_lib.so", "func");
* \endcode
*
* \code
* auto fp = import_mangled("test_lib.so", "func");
* \endcode
*
* If qualified member-functions are needed, this can be set by repeating the class name with const or volatile.
* All following signatures after the redifintion will use this, i.e. the latest.
*
* * * \code
* auto fp = import_mangled("test_lib.so", "func");
* \endcode
*
* \b Template \b parameter \b T: Type of the symbol that we are going to import. Must be explicitly specified.
*
* \param lib Path to shared library or shared library to load function from.
* \param name Null-terminated C or C++ mangled name of the function to import. Can handle std::string, char*, const char*.
* \param mode An mode that will be used on library load.
*
* \return callable object if T is a function type, or boost::shared_ptr if T is an object type.
*
* \throw \forcedlinkfs{system_error} if symbol does not exist or if the DLL/DSO was not loaded.
* Overload that accepts path also throws std::bad_alloc in case of insufficient memory.
*/
template
BOOST_DLL_MANGLED_IMPORT_RESULT_TYPE import_mangled(const boost::dll::fs::path& lib, const char* name,
load_mode::type mode = load_mode::default_mode)
{
typedef typename boost::dll::experimental::detail::mangled_import_type<
boost::dll::experimental::detail::sequence> type;
boost::dll::experimental::smart_library p(lib, mode);
//the load
return type::make(p, name);
}
//! \overload boost::dll::import(const boost::dll::fs::path& lib, const char* name, load_mode::type mode)
template
BOOST_DLL_MANGLED_IMPORT_RESULT_TYPE import_mangled(const boost::dll::fs::path& lib, const std::string& name,
load_mode::type mode = load_mode::default_mode)
{
return import_mangled(lib, name.c_str(), mode);
}
//! \overload boost::dll::import(const boost::dll::fs::path& lib, const char* name, load_mode::type mode)
template
BOOST_DLL_MANGLED_IMPORT_RESULT_TYPE import_mangled(const smart_library& lib, const char* name) {
typedef typename boost::dll::experimental::detail::mangled_import_type> type;
return type::make(lib, name);
}
//! \overload boost::dll::import(const boost::dll::fs::path& lib, const char* name, load_mode::type mode)
template
BOOST_DLL_MANGLED_IMPORT_RESULT_TYPE import_mangled(const smart_library& lib, const std::string& name) {
return import_mangled(lib, name.c_str());
}
//! \overload boost::dll::import(const boost::dll::fs::path& lib, const char* name, load_mode::type mode)
template
BOOST_DLL_MANGLED_IMPORT_RESULT_TYPE import_mangled(BOOST_RV_REF(smart_library) lib, const char* name) {
typedef typename boost::dll::experimental::detail::mangled_import_type> type;
return type::make(lib, name);
}
//! \overload boost::dll::import(const boost::dll::fs::path& lib, const char* name, load_mode::type mode)
template
BOOST_DLL_MANGLED_IMPORT_RESULT_TYPE import_mangled(BOOST_RV_REF(smart_library) lib, const std::string& name) {
return import_mangled(boost::move(lib), name.c_str());
}
//! \overload boost::dll::import(const boost::dll::fs::path& lib, const char* name, load_mode::type mode)
template
BOOST_DLL_MANGLED_IMPORT_RESULT_TYPE import_mangled(const shared_library& lib, const char* name) {
typedef typename boost::dll::experimental::detail::mangled_import_type> type;
boost::shared_ptr p = boost::make_shared(lib);
return type::make(p, name);
}
//! \overload boost::dll::import(const boost::dll::fs::path& lib, const char* name, load_mode::type mode)
template
BOOST_DLL_MANGLED_IMPORT_RESULT_TYPE import_mangled(const shared_library& lib, const std::string& name) {
return import_mangled(lib, name.c_str());
}
//! \overload boost::dll::import(const boost::dll::fs::path& lib, const char* name, load_mode::type mode)
template
BOOST_DLL_MANGLED_IMPORT_RESULT_TYPE import_mangled(BOOST_RV_REF(shared_library) lib, const char* name) {
typedef typename boost::dll::experimental::detail::mangled_import_type> type;
boost::dll::experimental::smart_library p(boost::move(lib));
return type::make(p, name);
}
//! \overload boost::dll::import(const boost::dll::fs::path& lib, const char* name, load_mode::type mode)
template
BOOST_DLL_MANGLED_IMPORT_RESULT_TYPE import_mangled(BOOST_RV_REF(shared_library) lib, const std::string& name) {
return import_mangled(boost::move(lib), name.c_str());
}
#undef BOOST_DLL_MANGLED_IMPORT_RESULT_TYPE
}}}
#endif /* BOOST_DLL_IMPORT_MANGLED_HPP_ */