mirror of
https://github.com/boostorg/dll.git
synced 2026-01-19 04:12:08 +00:00
Merge branch 'develop' of github.com:boostorg/dll into HEAD
This commit is contained in:
@@ -18,15 +18,11 @@ target_link_libraries(boost_dll
|
||||
Boost::config
|
||||
Boost::core
|
||||
Boost::filesystem
|
||||
Boost::function
|
||||
Boost::move
|
||||
Boost::predef
|
||||
Boost::smart_ptr
|
||||
Boost::spirit
|
||||
Boost::system
|
||||
Boost::throw_exception
|
||||
Boost::type_index
|
||||
Boost::type_traits
|
||||
Boost::winapi
|
||||
)
|
||||
|
||||
|
||||
@@ -10,15 +10,11 @@ constant boost_dependencies :
|
||||
/boost/config//boost_config
|
||||
/boost/core//boost_core
|
||||
/boost/filesystem//boost_filesystem
|
||||
/boost/function//boost_function
|
||||
/boost/move//boost_move
|
||||
/boost/predef//boost_predef
|
||||
/boost/smart_ptr//boost_smart_ptr
|
||||
/boost/spirit//boost_spirit
|
||||
/boost/system//boost_system
|
||||
/boost/throw_exception//boost_throw_exception
|
||||
/boost/type_index//boost_type_index
|
||||
/boost/type_traits//boost_type_traits
|
||||
/boost/winapi//boost_winapi ;
|
||||
|
||||
project /boost/dll
|
||||
|
||||
@@ -35,15 +35,8 @@ local doxygen_params =
|
||||
\"forcedlinkfs{1}=\\xmlonly<link linkend='boost.dll.fs.\\1'>boost::dll::fs::\\1</link>\\endxmlonly\" \\
|
||||
\"forcedmacrolink{1}=\\xmlonly<link linkend='\\1'>\\1</link>\\endxmlonly\" "
|
||||
<doxygen:param>"PREDEFINED= \\
|
||||
\"BOOST_RV_REF(T)=T&&\" \\
|
||||
\"BOOST_RV_REF(shared_library)=shared_library&&\" \\
|
||||
\"BOOST_COPY_ASSIGN_REF(shared_library)=const shared_library&\" \\
|
||||
\"BOOST_MOVABLE_BUT_NOT_COPYABLE(shared_library)= \\
|
||||
shared_library(const shared_library&) = delete; \\
|
||||
shared_library& operator=(const shared_library&) = delete; \" \\
|
||||
\"BOOST_DLL_IMPORT_RESULT_TYPE=result_type\" \\
|
||||
\"BOOST_DLL_MANGLED_IMPORT_RESULT_TYPE=result_type\" \\
|
||||
\"BOOST_EXPLICIT_OPERATOR_BOOL()=explicit operator bool() const noexcept;\" \\
|
||||
\"BOOST_DLL_DOXYGEN\" "
|
||||
;
|
||||
|
||||
|
||||
@@ -10,12 +10,11 @@
|
||||
The Boost.DLL is a header only library, but it depends on the following libraries
|
||||
and they must be available in order to compile programs that use Boost.DLL:
|
||||
|
||||
* Boost.System for the boost::system::error_code and boost::system::system_error classes.
|
||||
* Boost.System for the boost::system::system_error class.
|
||||
* Boost.Filesystem for directory manipulation.
|
||||
|
||||
Refcountable part of Boost.DLL also depends on:
|
||||
|
||||
* Boost.Function for creation of a callback system.
|
||||
* Boost.SharedPtr for reference counting.
|
||||
|
||||
[endsect]
|
||||
|
||||
@@ -17,7 +17,7 @@ boost::dll::shared_library lib("/test/boost/application/libtest_library.so");
|
||||
Now you can easily import symbols from that library using the `get` and `get_alias` member functions:
|
||||
```
|
||||
int plugin_constant = lib.get<const int>("integer_variable");
|
||||
boost::function<int()> f = lib.get<int()>("function_returning_int");
|
||||
auto function_ptr = lib.get<int()>("function_returning_int");
|
||||
int& i = lib.get_alias<int>("alias_to_int_variable");
|
||||
```
|
||||
In case of `boost::dll::shared_library` it is safe to use imported symbols only until `boost::dll::shared_library`
|
||||
|
||||
@@ -19,10 +19,9 @@ int main(int argc, char* argv[]) {
|
||||
/*<-*/ b2_workarounds::argv_to_path_guard guard(argc, argv); /*->*/
|
||||
boost::dll::fs::path shared_library_path(argv[1]); // argv[1] contains path to directory with our plugin library
|
||||
shared_library_path /= "my_plugin_aggregator";
|
||||
typedef boost::shared_ptr<my_plugin_api> (pluginapi_create_t)();
|
||||
boost::function<pluginapi_create_t> creator;
|
||||
|
||||
creator = boost::dll::import_alias<pluginapi_create_t>( // type of imported symbol must be explicitly specified
|
||||
using pluginapi_create_t = boost::shared_ptr<my_plugin_api>();
|
||||
auto creator = boost::dll::import_alias<pluginapi_create_t>( // type of imported symbol must be explicitly specified
|
||||
shared_library_path, // path to library
|
||||
"create_plugin", // symbol to import
|
||||
dll::load_mode::append_decorations // do append extensions and prefixes
|
||||
|
||||
@@ -27,9 +27,10 @@ std::size_t search_for_symbols(const std::vector<boost::dll::fs::path>& plugins)
|
||||
}
|
||||
|
||||
// library has symbol, importing...
|
||||
typedef boost::shared_ptr<my_plugin_api> (pluginapi_create_t)();
|
||||
boost::function<pluginapi_create_t> creator
|
||||
= dll::import_alias<pluginapi_create_t>(boost::move(lib), "create_plugin");
|
||||
using pluginapi_create_t = boost::shared_ptr<my_plugin_api>();
|
||||
auto creator = dll::import_alias<pluginapi_create_t>(
|
||||
std::move(lib), "create_plugin"
|
||||
);
|
||||
|
||||
std::cout << "Matching plugin name: " << creator()->name() << std::endl;
|
||||
++ plugins_found;
|
||||
|
||||
@@ -21,8 +21,7 @@ int main() {
|
||||
dll::shared_library self(dll::program_location());
|
||||
|
||||
std::cout << "Call function" << std::endl;
|
||||
boost::function<boost::shared_ptr<my_plugin_api>()> creator
|
||||
= self.get_alias<boost::shared_ptr<my_plugin_api>()>("create_plugin");
|
||||
auto creator = self.get_alias<boost::shared_ptr<my_plugin_api>()>("create_plugin");
|
||||
|
||||
std::cout << "Computed Value: " << creator()->calculate(2, 2) << std::endl;
|
||||
//<-
|
||||
|
||||
@@ -22,7 +22,7 @@ namespace dll = boost::dll;
|
||||
|
||||
class plugins_collector {
|
||||
// Name => plugin
|
||||
typedef boost::container::map<std::string, dll::shared_library> plugins_t;
|
||||
using plugins_t = boost::container::map<std::string, dll::shared_library>;
|
||||
|
||||
boost::dll::fs::path plugins_directory_;
|
||||
plugins_t plugins_;
|
||||
@@ -32,7 +32,7 @@ class plugins_collector {
|
||||
|
||||
// Gets `my_plugin_api` instance using "create_plugin" or "plugin" imports,
|
||||
// stores plugin with its name in the `plugins_` map.
|
||||
void insert_plugin(BOOST_RV_REF(dll::shared_library) lib);
|
||||
void insert_plugin(dll::shared_library&& lib);
|
||||
|
||||
public:
|
||||
plugins_collector(const boost::dll::fs::path& plugins_directory)
|
||||
@@ -52,8 +52,7 @@ public:
|
||||
//[plugcpp_plugins_collector_load_all
|
||||
void plugins_collector::load_all() {
|
||||
namespace fs = ::boost::dll::fs;
|
||||
typedef fs::path::string_type string_type;
|
||||
const string_type extension = dll::shared_library::suffix().native();
|
||||
const auto extension = dll::shared_library::suffix().native();
|
||||
|
||||
// Searching a folder for files with '.so' or '.dll' extension
|
||||
fs::recursive_directory_iterator endit;
|
||||
@@ -67,7 +66,7 @@ void plugins_collector::load_all() {
|
||||
}
|
||||
/*->*/
|
||||
// We found a file. Trying to load it
|
||||
boost::dll::fs::error_code error;
|
||||
std::error_code error;
|
||||
dll::shared_library plugin(it->path(), error);
|
||||
if (error) {
|
||||
continue;
|
||||
@@ -75,17 +74,17 @@ void plugins_collector::load_all() {
|
||||
std::cout << "Loaded (" << plugin.native() << "):" << it->path() << '\n';
|
||||
|
||||
// Gets plugin using "create_plugin" or "plugin" function
|
||||
insert_plugin(boost::move(plugin));
|
||||
insert_plugin(std::move(plugin));
|
||||
}
|
||||
|
||||
dll::shared_library plugin(dll::program_location());
|
||||
std::cout << "Loaded self\n";
|
||||
insert_plugin(boost::move(plugin));
|
||||
insert_plugin(std::move(plugin));
|
||||
}
|
||||
//]
|
||||
|
||||
//[plugcpp_plugins_collector_insert_plugin
|
||||
void plugins_collector::insert_plugin(BOOST_RV_REF(dll::shared_library) lib) {
|
||||
void plugins_collector::insert_plugin(dll::shared_library&& lib) {
|
||||
std::string plugin_name;
|
||||
if (lib.has("create_plugin")) {
|
||||
plugin_name = lib.get_alias<boost::shared_ptr<my_plugin_api>()>("create_plugin")()->name();
|
||||
@@ -96,7 +95,7 @@ void plugins_collector::insert_plugin(BOOST_RV_REF(dll::shared_library) lib) {
|
||||
}
|
||||
|
||||
if (plugins_.find(plugin_name) == plugins_.cend()) {
|
||||
plugins_[plugin_name] = boost::move(lib);
|
||||
plugins_[plugin_name] = std::move(lib);
|
||||
}
|
||||
}
|
||||
//]
|
||||
|
||||
@@ -10,14 +10,14 @@
|
||||
|
||||
//[plugcpp_on_unload
|
||||
#include <boost/dll/alias.hpp> // for BOOST_DLL_ALIAS
|
||||
#include <boost/function.hpp>
|
||||
#include <functional>
|
||||
#include <vector>
|
||||
|
||||
namespace my_namespace {
|
||||
|
||||
struct on_unload {
|
||||
typedef boost::function<void()> callback_t;
|
||||
typedef on_unload this_type;
|
||||
using callback_t = std::function<void()> ;
|
||||
using this_type = on_unload;
|
||||
|
||||
~on_unload() {
|
||||
for (std::size_t i = 0; i < callbacks_.size(); ++i) {
|
||||
|
||||
@@ -9,10 +9,10 @@
|
||||
|
||||
//[callplugcpp_tutorial6
|
||||
#include <boost/dll/import.hpp>
|
||||
#include <boost/function.hpp>
|
||||
#include <functional>
|
||||
#include <iostream>
|
||||
|
||||
typedef boost::function<void()> callback_t;
|
||||
using callback_t = std::function<void()> ;
|
||||
|
||||
void print_unloaded() {
|
||||
std::cout << "unloaded" << std::endl;
|
||||
@@ -23,16 +23,15 @@ int main(int argc, char* argv[]) {
|
||||
boost::dll::fs::path shared_library_path = /*<-*/ b2_workarounds::first_lib_from_argv(argc, argv); /*->*/ //=argv[1];
|
||||
|
||||
// loading library and getting a function from it
|
||||
boost::function<void(const callback_t&)> on_unload
|
||||
= boost::dll::import_alias<void(const callback_t&)>(
|
||||
shared_library_path, "on_unload"
|
||||
);
|
||||
std::function<void(const callback_t&)> on_unload = boost::dll::import_alias<void(const callback_t&)>(
|
||||
shared_library_path, "on_unload"
|
||||
);
|
||||
|
||||
on_unload(&print_unloaded); // adding a callback
|
||||
std::cout << "Before library unload." << std::endl;
|
||||
|
||||
// Releasing last reference to the library, so that it gets unloaded
|
||||
on_unload.clear();
|
||||
on_unload = {};
|
||||
std::cout << "After library unload." << std::endl;
|
||||
}
|
||||
//]
|
||||
|
||||
@@ -54,8 +54,8 @@ inline boost::shared_ptr<my_refcounting_api> bind(my_refcounting_api* plugin) {
|
||||
inline boost::shared_ptr<my_refcounting_api> get_plugin(
|
||||
boost::dll::fs::path path, const char* func_name)
|
||||
{
|
||||
typedef my_refcounting_api*(func_t)();
|
||||
boost::function<func_t> creator = boost::dll::import_alias<func_t>(
|
||||
using func_t = my_refcounting_api*();
|
||||
auto creator = boost::dll::import_alias<func_t>(
|
||||
path,
|
||||
func_name,
|
||||
boost::dll::load_mode::append_decorations // will be ignored for executable
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
//[callplugcpp_tutorial9
|
||||
#include <boost/dll/import.hpp> // for dll::import
|
||||
#include <boost/dll/shared_library.hpp> // for dll::shared_library
|
||||
#include <boost/function.hpp>
|
||||
#include <functional>
|
||||
#include <iostream>
|
||||
#include <windows.h>
|
||||
|
||||
@@ -29,15 +29,14 @@ int main() {
|
||||
);
|
||||
std::cout << "0.0 GetStdHandle() returned " << get_std_handle(STD_OUTPUT_HANDLE) << std::endl;
|
||||
|
||||
// You may put the `get_std_handle` into boost::function<>. But boost::function<Signature> can not compile with
|
||||
// You may put the `get_std_handle` into std::function<>. But std::function<Signature> may not compile with
|
||||
// Signature template parameter that contains calling conventions, so you'll have to remove the calling convention.
|
||||
boost::function<HANDLE(DWORD)> get_std_handle2 = get_std_handle;
|
||||
std::function<HANDLE(DWORD)> get_std_handle2 = get_std_handle;
|
||||
std::cout << "0.1 GetStdHandle() returned " << get_std_handle2(STD_OUTPUT_HANDLE) << std::endl;
|
||||
/*<-*/
|
||||
#endif /*->*/
|
||||
|
||||
// OPTION #1, does not require C++11. But without C++11 dll::import<> can not handle calling conventions,
|
||||
// so you'll need to hand write the import.
|
||||
// OPTION #1, hand write the import.
|
||||
dll::shared_library lib("Kernel32.dll", dll::load_mode::search_system_folders);
|
||||
GetStdHandle_t& func = lib.get<GetStdHandle_t>("GetStdHandle");
|
||||
|
||||
|
||||
@@ -44,7 +44,7 @@ namespace boost { namespace dll {
|
||||
#define BOOST_DLL_SELECTANY __declspec(selectany)
|
||||
|
||||
#define BOOST_DLL_SECTION(SectionName, Permissions) \
|
||||
static_assert( \
|
||||
static_assert( \
|
||||
sizeof(#SectionName) < 10, \
|
||||
"Some platforms require section names to be at most 8 bytes" \
|
||||
); \
|
||||
@@ -83,7 +83,7 @@ namespace boost { namespace dll {
|
||||
* \param Permissions Can be "read" or "write" (without quotes!).
|
||||
*/
|
||||
#define BOOST_DLL_SECTION(SectionName, Permissions) \
|
||||
static_assert( \
|
||||
static_assert( \
|
||||
sizeof(#SectionName) < 10, \
|
||||
"Some platforms require section names to be at most 8 bytes" \
|
||||
); \
|
||||
@@ -92,7 +92,7 @@ namespace boost { namespace dll {
|
||||
#else // #if !BOOST_OS_MACOS && !BOOST_OS_IOS
|
||||
|
||||
#define BOOST_DLL_SECTION(SectionName, Permissions) \
|
||||
static_assert( \
|
||||
static_assert( \
|
||||
sizeof(#SectionName) < 10, \
|
||||
"Some platforms require section names to be at most 8 bytes" \
|
||||
); \
|
||||
@@ -184,7 +184,7 @@ namespace boost { namespace dll {
|
||||
#else
|
||||
// Note: we can not use `aggressive_ptr_cast` here, because in that case GCC applies
|
||||
// different permissions to the section and it causes Segmentation fault.
|
||||
// Note: we can not use `boost::addressof()` here, because in that case GCC
|
||||
// Note: we can not use `std::addressof()` here, because in that case GCC
|
||||
// may optimize away the FunctionOrVar instance and we'll get a pointer to unexisting symbol.
|
||||
/*!
|
||||
* \brief Same as \forcedmacrolink{BOOST_DLL_ALIAS} but puts alias name into the user specified section.
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
#endif
|
||||
|
||||
#ifdef BOOST_DLL_DOXYGEN
|
||||
/// Define this macro to make Boost.DLL use C++17's std::filesystem::path, std::system_error and std::error_code.
|
||||
/// Define this macro to make Boost.DLL use C++17's std::filesystem::path and std::system_error.
|
||||
#define BOOST_DLL_USE_STD_FS BOOST_DLL_USE_STD_FS
|
||||
|
||||
/// This namespace contains aliases to the Boost or C++17 classes. Aliases are configured using BOOST_DLL_USE_STD_FS macro.
|
||||
@@ -38,19 +38,17 @@ using system_error = std::conditional_t<BOOST_DLL_USE_STD_FS, std::system_error,
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef BOOST_DLL_USE_STD_FS
|
||||
#include <filesystem>
|
||||
|
||||
#include <system_error>
|
||||
|
||||
namespace boost { namespace dll { namespace fs {
|
||||
|
||||
using namespace std::filesystem;
|
||||
|
||||
using std::error_code;
|
||||
using std::system_error;
|
||||
using std::make_error_code;
|
||||
using std::errc;
|
||||
using std::system_category;
|
||||
|
||||
}}}
|
||||
|
||||
@@ -58,18 +56,14 @@ using std::system_category;
|
||||
|
||||
#include <boost/filesystem/path.hpp>
|
||||
#include <boost/filesystem/operations.hpp>
|
||||
#include <boost/system/error_code.hpp>
|
||||
#include <boost/system/system_error.hpp>
|
||||
#include <boost/system/error_code.hpp>
|
||||
|
||||
namespace boost { namespace dll { namespace fs {
|
||||
|
||||
using namespace boost::filesystem;
|
||||
|
||||
using boost::system::error_code;
|
||||
using boost::system::system_error;
|
||||
using boost::system::errc::make_error_code;
|
||||
namespace errc = boost::system::errc;
|
||||
using boost::system::system_category;
|
||||
|
||||
}}}
|
||||
|
||||
|
||||
@@ -13,15 +13,9 @@
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/core/addressof.hpp>
|
||||
#include <boost/core/enable_if.hpp>
|
||||
#include <boost/type_traits/is_pointer.hpp>
|
||||
#include <boost/type_traits/is_member_pointer.hpp>
|
||||
#include <boost/type_traits/is_void.hpp>
|
||||
#include <boost/type_traits/is_reference.hpp>
|
||||
#include <boost/type_traits/remove_pointer.hpp>
|
||||
#include <boost/type_traits/remove_reference.hpp>
|
||||
#include <cstring> // std::memcpy
|
||||
#include <memory>
|
||||
#include <type_traits>
|
||||
|
||||
#if defined(__GNUC__) && defined(__GNUC_MINOR__) && (__GNUC__ * 100 + __GNUC_MINOR__ > 301)
|
||||
# pragma GCC system_header
|
||||
@@ -32,17 +26,17 @@ namespace boost { namespace dll { namespace detail {
|
||||
// GCC warns when reinterpret_cast between function pointer and object pointer occur.
|
||||
// This method suppress the warnings and ensures that such casts are safe.
|
||||
template <class To, class From>
|
||||
BOOST_FORCEINLINE typename boost::disable_if_c<boost::is_member_pointer<To>::value || boost::is_reference<To>::value || boost::is_member_pointer<From>::value, To>::type
|
||||
aggressive_ptr_cast(From v) BOOST_NOEXCEPT
|
||||
BOOST_FORCEINLINE typename std::enable_if<!std::is_member_pointer<To>::value && !std::is_reference<To>::value && !std::is_member_pointer<From>::value, To>::type
|
||||
aggressive_ptr_cast(From v) noexcept
|
||||
{
|
||||
static_assert(
|
||||
boost::is_pointer<To>::value && boost::is_pointer<From>::value,
|
||||
std::is_pointer<To>::value && std::is_pointer<From>::value,
|
||||
"`agressive_ptr_cast` function must be used only for pointer casting."
|
||||
);
|
||||
|
||||
static_assert(
|
||||
boost::is_void< typename boost::remove_pointer<To>::type >::value
|
||||
|| boost::is_void< typename boost::remove_pointer<From>::type >::value,
|
||||
std::is_void< typename std::remove_pointer<To>::type >::value
|
||||
|| std::is_void< typename std::remove_pointer<From>::type >::value,
|
||||
"`agressive_ptr_cast` function must be used only for casting to or from void pointers."
|
||||
);
|
||||
|
||||
@@ -60,25 +54,25 @@ BOOST_FORCEINLINE typename boost::disable_if_c<boost::is_member_pointer<To>::val
|
||||
#endif
|
||||
|
||||
template <class To, class From>
|
||||
BOOST_FORCEINLINE typename boost::disable_if_c<!boost::is_reference<To>::value || boost::is_member_pointer<From>::value, To>::type
|
||||
aggressive_ptr_cast(From v) BOOST_NOEXCEPT
|
||||
BOOST_FORCEINLINE typename std::enable_if<std::is_reference<To>::value && !std::is_member_pointer<From>::value, To>::type
|
||||
aggressive_ptr_cast(From v) noexcept
|
||||
{
|
||||
static_assert(
|
||||
boost::is_pointer<From>::value,
|
||||
std::is_pointer<From>::value,
|
||||
"`agressive_ptr_cast` function must be used only for pointer casting."
|
||||
);
|
||||
|
||||
static_assert(
|
||||
boost::is_void< typename boost::remove_pointer<From>::type >::value,
|
||||
std::is_void< typename std::remove_pointer<From>::type >::value,
|
||||
"`agressive_ptr_cast` function must be used only for casting to or from void pointers."
|
||||
);
|
||||
|
||||
static_assert(
|
||||
sizeof(v) == sizeof(typename boost::remove_reference<To>::type*),
|
||||
sizeof(v) == sizeof(typename std::remove_reference<To>::type*),
|
||||
"Pointer to function and pointer to object differ in size on your platform."
|
||||
);
|
||||
return static_cast<To>(
|
||||
**reinterpret_cast<typename boost::remove_reference<To>::type**>(
|
||||
**reinterpret_cast<typename std::remove_reference<To>::type**>(
|
||||
v
|
||||
)
|
||||
);
|
||||
@@ -89,16 +83,16 @@ BOOST_FORCEINLINE typename boost::disable_if_c<!boost::is_reference<To>::value |
|
||||
#endif
|
||||
|
||||
template <class To, class From>
|
||||
BOOST_FORCEINLINE typename boost::disable_if_c<!boost::is_member_pointer<To>::value || boost::is_member_pointer<From>::value, To>::type
|
||||
aggressive_ptr_cast(From v) BOOST_NOEXCEPT
|
||||
BOOST_FORCEINLINE typename std::enable_if<std::is_member_pointer<To>::value && !std::is_member_pointer<From>::value, To>::type
|
||||
aggressive_ptr_cast(From v) noexcept
|
||||
{
|
||||
static_assert(
|
||||
boost::is_pointer<From>::value,
|
||||
std::is_pointer<From>::value,
|
||||
"`agressive_ptr_cast` function must be used only for pointer casting."
|
||||
);
|
||||
|
||||
static_assert(
|
||||
boost::is_void< typename boost::remove_pointer<From>::type >::value,
|
||||
std::is_void< typename std::remove_pointer<From>::type >::value,
|
||||
"`agressive_ptr_cast` function must be used only for casting to or from void pointers."
|
||||
);
|
||||
|
||||
@@ -108,16 +102,16 @@ BOOST_FORCEINLINE typename boost::disable_if_c<!boost::is_member_pointer<To>::va
|
||||
}
|
||||
|
||||
template <class To, class From>
|
||||
BOOST_FORCEINLINE typename boost::disable_if_c<boost::is_member_pointer<To>::value || !boost::is_member_pointer<From>::value, To>::type
|
||||
aggressive_ptr_cast(From /* v */) BOOST_NOEXCEPT
|
||||
BOOST_FORCEINLINE typename std::enable_if<!std::is_member_pointer<To>::value && std::is_member_pointer<From>::value, To>::type
|
||||
aggressive_ptr_cast(From /* v */) noexcept
|
||||
{
|
||||
static_assert(
|
||||
boost::is_pointer<To>::value,
|
||||
std::is_pointer<To>::value,
|
||||
"`agressive_ptr_cast` function must be used only for pointer casting."
|
||||
);
|
||||
|
||||
static_assert(
|
||||
boost::is_void< typename boost::remove_pointer<To>::type >::value,
|
||||
std::is_void< typename std::remove_pointer<To>::type >::value,
|
||||
"`agressive_ptr_cast` function must be used only for casting to or from void pointers."
|
||||
);
|
||||
|
||||
|
||||
@@ -130,7 +130,7 @@ template<typename Class, typename Lib>
|
||||
destructor<Class> load_dtor(Lib & lib, const mangled_storage_impl::dtor_sym & dt) {
|
||||
typedef typename destructor<Class>::standard_t standard_t;
|
||||
//@apolukhin That does NOT work this way with MSVC-14 x32 via memcpy. The x64 is different.
|
||||
//standard_t dtor = &lib.template get< typename boost::remove_pointer<standard_t>::type >(dt);
|
||||
//standard_t dtor = &lib.template get< typename std::remove_pointer<standard_t>::type >(dt);
|
||||
void * buf = &lib.template get<unsigned char>(dt);
|
||||
standard_t dtor;
|
||||
std::memcpy(&dtor, &buf, sizeof(dtor));
|
||||
@@ -175,11 +175,11 @@ destructor<Class> load_dtor(Lib & lib, const mangled_storage_impl::dtor_sym & dt
|
||||
|
||||
//see here for the abi http://mentorembedded.github.io/cxx-abi/abi.html#mangling-special-ctor-dtor
|
||||
if (!dt.D1.empty()) {
|
||||
s = &lib.template get< typename boost::remove_pointer<stand>::type >(dt.D1);
|
||||
s = &lib.template get< typename std::remove_pointer<stand>::type >(dt.D1);
|
||||
}
|
||||
|
||||
if (!dt.D0.empty()) {
|
||||
d = &lib.template get< typename boost::remove_pointer<delet>::type >(dt.D0);
|
||||
d = &lib.template get< typename std::remove_pointer<delet>::type >(dt.D0);
|
||||
}
|
||||
|
||||
return destructor<Class>(s,d);
|
||||
|
||||
@@ -8,19 +8,15 @@
|
||||
#define BOOST_DLL_DETAIL_DEMANGLING_ITANIUM_HPP_
|
||||
|
||||
#include <boost/dll/detail/demangling/mangled_storage_base.hpp>
|
||||
#include <iterator>
|
||||
|
||||
#include <algorithm>
|
||||
#include <boost/type_traits/is_const.hpp>
|
||||
#include <boost/type_traits/is_volatile.hpp>
|
||||
#include <boost/type_traits/is_rvalue_reference.hpp>
|
||||
#include <boost/type_traits/is_lvalue_reference.hpp>
|
||||
#include <boost/type_traits/function_traits.hpp>
|
||||
#include <iterator>
|
||||
#include <type_traits>
|
||||
|
||||
|
||||
namespace boost { namespace dll { namespace detail {
|
||||
|
||||
|
||||
|
||||
class mangled_storage_impl : public mangled_storage_base
|
||||
{
|
||||
template<typename T>
|
||||
@@ -185,22 +181,22 @@ namespace parser
|
||||
}
|
||||
};
|
||||
|
||||
inline std::string const_rule_impl(true_type ) {return " const";}
|
||||
inline std::string const_rule_impl(false_type) {return "";}
|
||||
inline std::string const_rule_impl(std::true_type ) {return " const";}
|
||||
inline std::string const_rule_impl(std::false_type) {return "";}
|
||||
template<typename T>
|
||||
std::string const_rule() {using t = is_const<typename remove_reference<T>::type>; return const_rule_impl(t());}
|
||||
std::string const_rule() {using t = std::is_const<typename std::remove_reference<T>::type>; return const_rule_impl(t());}
|
||||
|
||||
inline std::string volatile_rule_impl(true_type ) {return " volatile";}
|
||||
inline std::string volatile_rule_impl(false_type) {return "";}
|
||||
inline std::string volatile_rule_impl(std::true_type ) {return " volatile";}
|
||||
inline std::string volatile_rule_impl(std::false_type) {return "";}
|
||||
template<typename T>
|
||||
std::string volatile_rule() {using t = is_volatile<typename remove_reference<T>::type>; return volatile_rule_impl(t());}
|
||||
std::string volatile_rule() {using t = std::is_volatile<typename std::remove_reference<T>::type>; return volatile_rule_impl(t());}
|
||||
|
||||
inline std::string reference_rule_impl(false_type, false_type) {return "";}
|
||||
inline std::string reference_rule_impl(true_type, false_type) {return "&" ;}
|
||||
inline std::string reference_rule_impl(false_type, true_type ) {return "&&";}
|
||||
inline std::string reference_rule_impl(std::false_type, std::false_type) {return "";}
|
||||
inline std::string reference_rule_impl(std::true_type, std::false_type) {return "&" ;}
|
||||
inline std::string reference_rule_impl(std::false_type, std::true_type ) {return "&&";}
|
||||
|
||||
template<typename T>
|
||||
std::string reference_rule() {using t_l = is_lvalue_reference<T>; using t_r = is_rvalue_reference<T>; return reference_rule_impl(t_l(), t_r());}
|
||||
std::string reference_rule() {using t_l = std::is_lvalue_reference<T>; using t_r = std::is_rvalue_reference<T>; return reference_rule_impl(t_l(), t_r());}
|
||||
|
||||
//it takes a string, because it may be overloaded.
|
||||
template<typename Return, typename Arg>
|
||||
|
||||
@@ -10,10 +10,12 @@
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <type_traits>
|
||||
|
||||
#include <boost/dll/detail/demangling/demangle_symbol.hpp>
|
||||
#include <boost/dll/library_info.hpp>
|
||||
#include <boost/type_index/ctti_type_index.hpp>
|
||||
#include <boost/type_traits/remove_reference.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace dll { namespace detail {
|
||||
|
||||
|
||||
@@ -8,16 +8,12 @@
|
||||
#define BOOST_DLL_DETAIL_DEMANGLING_MSVC_HPP_
|
||||
|
||||
#include <boost/dll/detail/demangling/mangled_storage_base.hpp>
|
||||
|
||||
#include <boost/core/detail/string_view.hpp>
|
||||
|
||||
#include <iterator>
|
||||
#include <algorithm>
|
||||
#include <boost/type_traits/is_const.hpp>
|
||||
#include <boost/type_traits/is_volatile.hpp>
|
||||
#include <boost/type_traits/is_lvalue_reference.hpp>
|
||||
#include <boost/type_traits/is_rvalue_reference.hpp>
|
||||
#include <boost/type_traits/function_traits.hpp>
|
||||
#include <boost/type_traits/remove_reference.hpp>
|
||||
|
||||
#include <boost/spirit/home/x3.hpp>
|
||||
#include <type_traits>
|
||||
|
||||
namespace boost { namespace dll { namespace detail {
|
||||
|
||||
@@ -26,11 +22,6 @@ class mangled_storage_impl : public mangled_storage_base
|
||||
template<typename T>
|
||||
struct dummy {};
|
||||
|
||||
template<typename Return, typename ...Args>
|
||||
std::vector<std::string> get_func_params(dummy<Return(Args...)>) const
|
||||
{
|
||||
return {get_name<Args>()...};
|
||||
}
|
||||
template<typename Return, typename ...Args>
|
||||
std::string get_return_type(dummy<Return(Args...)>) const
|
||||
{
|
||||
@@ -93,134 +84,247 @@ void mangled_storage_impl::trim_typename(std::string & val)
|
||||
}
|
||||
}
|
||||
|
||||
namespace parser {
|
||||
|
||||
namespace parser
|
||||
{
|
||||
namespace x3 = spirit::x3;
|
||||
|
||||
inline auto ptr_rule_impl(std::integral_constant<std::size_t, 32>)
|
||||
{
|
||||
return -((-x3::space) >> "__ptr32");
|
||||
}
|
||||
inline auto ptr_rule_impl(std::integral_constant<std::size_t, 64>)
|
||||
{
|
||||
return -((-x3::space) >> "__ptr64");
|
||||
inline bool try_consume_prefix(boost::core::string_view& s, boost::core::string_view prefix) {
|
||||
const bool result = s.starts_with(prefix);
|
||||
if (result) {
|
||||
s.remove_prefix(prefix.size());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
inline auto ptr_rule() {
|
||||
return ptr_rule_impl(std::integral_constant<std::size_t, sizeof(std::size_t)*8>());
|
||||
inline bool ignore_prefix(boost::core::string_view& s, boost::core::string_view prefix) {
|
||||
parser::try_consume_prefix(s, prefix);
|
||||
return true;
|
||||
}
|
||||
|
||||
inline void consume_ptrs(boost::core::string_view& s) {
|
||||
do {
|
||||
while (parser::try_consume_prefix(s, " ")) {}
|
||||
} while (parser::try_consume_prefix(s, "__ptr32") || parser::try_consume_prefix(s, "__ptr64"));
|
||||
}
|
||||
|
||||
auto const visibility = ("public:" | x3::lit("protected:") | "private:");
|
||||
auto const virtual_ = x3::space >> "virtual";
|
||||
auto const static_ = x3::space >> x3::lit("static") ;
|
||||
|
||||
inline auto const_rule_impl(true_type ) {return x3::space >> "const";};
|
||||
inline auto const_rule_impl(false_type) {return x3::eps;};
|
||||
template<typename T>
|
||||
auto const_rule() {using t = is_const<typename remove_reference<T>::type>; return const_rule_impl(t());}
|
||||
|
||||
inline auto volatile_rule_impl(true_type ) {return x3::space >> "volatile";};
|
||||
inline auto volatile_rule_impl(false_type) {return x3::eps;};
|
||||
template<typename T>
|
||||
auto volatile_rule() {using t = is_volatile<typename remove_reference<T>::type>; return volatile_rule_impl(t());}
|
||||
|
||||
|
||||
inline auto inv_const_rule_impl(true_type ) {return "const" >> x3::space ;};
|
||||
inline auto inv_const_rule_impl(false_type) {return x3::eps;};
|
||||
template<typename T>
|
||||
auto inv_const_rule() {using t = is_const<typename remove_reference<T>::type>; return inv_const_rule_impl(t());}
|
||||
|
||||
inline auto inv_volatile_rule_impl(true_type ) {return "volatile" >> x3::space;};
|
||||
inline auto inv_volatile_rule_impl(false_type) {return x3::eps;};
|
||||
template<typename T>
|
||||
auto inv_volatile_rule() {using t = is_volatile<typename remove_reference<T>::type>; return inv_volatile_rule_impl(t());}
|
||||
|
||||
|
||||
inline auto reference_rule_impl(false_type, false_type) {return x3::eps;}
|
||||
inline auto reference_rule_impl(true_type, false_type) {return x3::space >>"&" ;}
|
||||
inline auto reference_rule_impl(false_type, true_type ) {return x3::space >>"&&" ;}
|
||||
|
||||
|
||||
template<typename T>
|
||||
auto reference_rule() {using t_l = is_lvalue_reference<T>; using t_r = is_rvalue_reference<T>; return reference_rule_impl(t_l(), t_r());}
|
||||
|
||||
auto const class_ = ("class" | x3::lit("struct"));
|
||||
|
||||
//it takes a string, because it may be overloaded.
|
||||
template<typename T>
|
||||
auto type_rule(const std::string & type_name)
|
||||
{
|
||||
using namespace std;
|
||||
|
||||
return -(class_ >> x3::space)>> x3::string(type_name) >>
|
||||
const_rule<T>() >>
|
||||
volatile_rule<T>() >>
|
||||
reference_rule<T>() >>
|
||||
ptr_rule();
|
||||
inline bool ignore_ptrs(boost::core::string_view& s) {
|
||||
parser::consume_ptrs(s);
|
||||
return true;
|
||||
}
|
||||
template<>
|
||||
inline auto type_rule<void>(const std::string &) { return x3::string("void"); };
|
||||
|
||||
auto const cdecl_ = "__cdecl" >> x3::space;
|
||||
auto const stdcall = "__stdcall" >> x3::space;
|
||||
#if defined(_WIN64)//seems to be necessary by msvc 14-x64
|
||||
auto const thiscall = "__cdecl" >> x3::space;
|
||||
#else
|
||||
auto const thiscall = "__thiscall" >> x3::space;
|
||||
#endif
|
||||
inline bool try_consume_visibility(boost::core::string_view& s) {
|
||||
return parser::try_consume_prefix(s, "public:")
|
||||
|| parser::try_consume_prefix(s, "protected:")
|
||||
|| parser::try_consume_prefix(s, "private:");
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool try_consume_type(boost::core::string_view& s, const mangled_storage_impl& ms) {
|
||||
if (std::is_void<T>::value) {
|
||||
return parser::try_consume_prefix(s, "void");
|
||||
}
|
||||
|
||||
parser::ignore_prefix(s, "class ");
|
||||
parser::ignore_prefix(s, "struct ");
|
||||
|
||||
const auto& mangled_name = ms.get_name<T>();
|
||||
if (!parser::try_consume_prefix(s, mangled_name)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (std::is_const<typename std::remove_reference<T>::type>::value) {
|
||||
if (!parser::try_consume_prefix(s, " const")) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (std::is_volatile<typename std::remove_reference<T>::type>::value) {
|
||||
if (!parser::try_consume_prefix(s, " volatile")) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (std::is_rvalue_reference<T>::value) {
|
||||
if (!parser::try_consume_prefix(s, " &&")) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (std::is_lvalue_reference<T>::value) {
|
||||
if (!parser::try_consume_prefix(s, " &")) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return parser::ignore_ptrs(s);
|
||||
}
|
||||
|
||||
inline bool try_consume_thiscall(boost::core::string_view& s) {
|
||||
parser::try_consume_prefix(s, " ");
|
||||
return parser::try_consume_prefix(s, "__cdecl ") // Win 64bit
|
||||
|| parser::try_consume_prefix(s, "__thiscall "); // Win 32bit
|
||||
}
|
||||
|
||||
template<typename Return, typename Arg>
|
||||
auto arg_list(const mangled_storage_impl & ms, Return (*)(Arg))
|
||||
{
|
||||
using namespace std;
|
||||
|
||||
return type_rule<Arg>(ms.get_name<Arg>());
|
||||
bool try_consume_arg_list(boost::core::string_view& s, const mangled_storage_impl& ms, Return (*)(Arg)) {
|
||||
return parser::try_consume_type<Arg>(s, ms);
|
||||
}
|
||||
|
||||
template<typename Return, typename First, typename Second, typename ...Args>
|
||||
auto arg_list(const mangled_storage_impl & ms, Return (*)(First, Second, Args...))
|
||||
{
|
||||
|
||||
bool try_consume_arg_list(boost::core::string_view& s, const mangled_storage_impl& ms, Return (*)(First, Second, Args...)) {
|
||||
using next_type = Return (*)(Second, Args...);
|
||||
return type_rule<First>(ms.get_name<First>()) >> x3::char_(',') >> arg_list(ms, next_type());
|
||||
return parser::try_consume_type<First>(s, ms)
|
||||
&& parser::try_consume_prefix(s, ",")
|
||||
&& parser::try_consume_arg_list(s, ms, next_type());
|
||||
}
|
||||
|
||||
template<typename Return>
|
||||
auto arg_list(const mangled_storage_impl& /*ms*/, Return (*)())
|
||||
{
|
||||
return x3::string("void");
|
||||
bool try_consume_arg_list(boost::core::string_view& s, const mangled_storage_impl& ms, Return (*)()) {
|
||||
return parser::try_consume_type<void>(s, ms);
|
||||
}
|
||||
}
|
||||
|
||||
class is_destructor_with_name {
|
||||
const std::string& dtor_name_;
|
||||
|
||||
template<typename T> std::string mangled_storage_impl::get_variable(const std::string &name) const
|
||||
{
|
||||
using namespace std;
|
||||
using namespace boost;
|
||||
public:
|
||||
explicit is_destructor_with_name(const std::string& dtor_name)
|
||||
: dtor_name_(dtor_name) {}
|
||||
|
||||
namespace x3 = spirit::x3;
|
||||
using namespace parser;
|
||||
inline bool operator()(boost::core::string_view s) const {
|
||||
return parser::try_consume_visibility(s)
|
||||
&& parser::ignore_prefix(s, " virtual")
|
||||
&& parser::try_consume_thiscall(s)
|
||||
&& parser::try_consume_prefix(s, dtor_name_)
|
||||
&& parser::ignore_ptrs(s)
|
||||
&& s.empty();
|
||||
}
|
||||
|
||||
auto type_name = get_name<T>();
|
||||
inline bool operator()(const mangled_storage_base::entry& e) const {
|
||||
return (*this)(boost::core::string_view(e.demangled.data(), e.demangled.size()));
|
||||
}
|
||||
};
|
||||
|
||||
auto matcher =
|
||||
-(visibility >> static_ >> x3::space) >> //it may be a static class-member
|
||||
parser::type_rule<T>(type_name) >> x3::space >>
|
||||
name;
|
||||
template<typename T>
|
||||
class is_variable_with_name {
|
||||
const std::string& variable_name_;
|
||||
const mangled_storage_impl& ms_;
|
||||
|
||||
auto predicate = [&](const mangled_storage_base::entry & e)
|
||||
{
|
||||
if (e.demangled == name)//maybe not mangled,
|
||||
return true;
|
||||
public:
|
||||
is_variable_with_name(const std::string& variable_name, const mangled_storage_impl& ms)
|
||||
: variable_name_(variable_name), ms_(ms) {}
|
||||
|
||||
auto itr = e.demangled.begin();
|
||||
auto end = e.demangled.end();
|
||||
auto res = x3::parse(itr, end, matcher);
|
||||
return res && (itr == end);
|
||||
};
|
||||
inline bool operator()(boost::core::string_view s) const {
|
||||
if (parser::try_consume_visibility(s) && !parser::try_consume_prefix(s, " static ")) {
|
||||
return false;
|
||||
}
|
||||
|
||||
auto found = std::find_if(storage_.begin(), storage_.end(), predicate);
|
||||
return parser::try_consume_type<T>(s, ms_)
|
||||
&& parser::try_consume_prefix(s, variable_name_)
|
||||
&& s.empty();
|
||||
}
|
||||
|
||||
inline bool operator()(const mangled_storage_base::entry& e) const {
|
||||
return (*this)(boost::core::string_view(e.demangled.data(), e.demangled.size()));
|
||||
}
|
||||
};
|
||||
|
||||
template <class Signature>
|
||||
class is_constructor_with_name {
|
||||
const std::string& ctor_name_;
|
||||
const mangled_storage_impl& ms_;
|
||||
|
||||
public:
|
||||
is_constructor_with_name(const std::string& ctor_name, const mangled_storage_impl& ms)
|
||||
: ctor_name_(ctor_name), ms_(ms) {}
|
||||
|
||||
inline bool operator()(boost::core::string_view s) const {
|
||||
return parser::try_consume_visibility(s)
|
||||
&& parser::try_consume_thiscall(s)
|
||||
&& parser::try_consume_prefix(s, ctor_name_)
|
||||
&& parser::try_consume_prefix(s, "(")
|
||||
&& parser::try_consume_arg_list(s, ms_, Signature())
|
||||
&& parser::try_consume_prefix(s, ")")
|
||||
&& parser::ignore_ptrs(s)
|
||||
&& s.empty();
|
||||
}
|
||||
|
||||
inline bool operator()(const mangled_storage_base::entry& e) const {
|
||||
return (*this)(boost::core::string_view(e.demangled.data(), e.demangled.size()));
|
||||
}
|
||||
};
|
||||
|
||||
template <class Signature>
|
||||
class is_function_with_name;
|
||||
|
||||
template <class Result, class... Args>
|
||||
class is_function_with_name<Result(*)(Args...)> {
|
||||
const std::string& function_name_;
|
||||
const mangled_storage_impl& ms_;
|
||||
|
||||
public:
|
||||
is_function_with_name(const std::string& function_name, const mangled_storage_impl& ms)
|
||||
: function_name_(function_name), ms_(ms) {}
|
||||
|
||||
inline bool operator()(boost::core::string_view s) const {
|
||||
if (parser::try_consume_visibility(s) && !parser::try_consume_prefix(s, " static ")) {
|
||||
return false;
|
||||
}
|
||||
|
||||
using Signature = Result(*)(Args...);
|
||||
return parser::try_consume_type<Result>(s, ms_)
|
||||
&& parser::ignore_prefix(s, " ")
|
||||
&& parser::try_consume_prefix(s, "__cdecl ")
|
||||
&& parser::try_consume_prefix(s, function_name_)
|
||||
&& parser::try_consume_prefix(s, "(")
|
||||
&& parser::try_consume_arg_list(s, ms_, Signature())
|
||||
&& parser::try_consume_prefix(s, ")")
|
||||
&& parser::ignore_ptrs(s)
|
||||
&& s.empty();
|
||||
}
|
||||
|
||||
inline bool operator()(const mangled_storage_base::entry& e) const {
|
||||
return (*this)(boost::core::string_view(e.demangled.data(), e.demangled.size()));
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Class, typename Func>
|
||||
class is_mem_fn_with_name;
|
||||
|
||||
template <typename Class, class Result, class... Args>
|
||||
class is_mem_fn_with_name<Class, Result(*)(Args...)> {
|
||||
const std::string& function_name_;
|
||||
const mangled_storage_impl& ms_;
|
||||
|
||||
public:
|
||||
is_mem_fn_with_name(const std::string& function_name, const mangled_storage_impl& ms)
|
||||
: function_name_(function_name), ms_(ms) {}
|
||||
|
||||
inline bool operator()(boost::core::string_view s) const {
|
||||
using Signature = Result(*)(Args...);
|
||||
return parser::try_consume_visibility(s)
|
||||
&& parser::ignore_prefix(s, " virtual")
|
||||
&& parser::try_consume_prefix(s, " ")
|
||||
&& parser::try_consume_type<Result>(s, ms_)
|
||||
&& parser::try_consume_thiscall(s)
|
||||
&& parser::try_consume_type<typename std::remove_cv<Class>::type>(s, ms_)
|
||||
&& parser::try_consume_prefix(s, "::")
|
||||
&& parser::try_consume_prefix(s, function_name_)
|
||||
&& parser::try_consume_prefix(s, "(")
|
||||
&& parser::try_consume_arg_list(s, ms_, Signature())
|
||||
&& parser::try_consume_prefix(s, ")")
|
||||
&& (!std::is_const<Class>::value || parser::try_consume_prefix(s, "const "))
|
||||
&& (!std::is_volatile<Class>::value || parser::try_consume_prefix(s, "volatile "))
|
||||
&& parser::ignore_ptrs(s)
|
||||
&& s.empty();
|
||||
}
|
||||
|
||||
inline bool operator()(const mangled_storage_base::entry& e) const {
|
||||
return (*this)(boost::core::string_view(e.demangled.data(), e.demangled.size()));
|
||||
}
|
||||
};
|
||||
} // namespace parser
|
||||
|
||||
template<typename T>
|
||||
std::string mangled_storage_impl::get_variable(const std::string &name) const {
|
||||
const auto found = std::find_if(storage_.begin(), storage_.end(), parser::is_variable_with_name<T>(name, *this));
|
||||
|
||||
if (found != storage_.end())
|
||||
return found->mangled;
|
||||
@@ -228,73 +332,19 @@ template<typename T> std::string mangled_storage_impl::get_variable(const std::s
|
||||
return "";
|
||||
}
|
||||
|
||||
template<typename Func> std::string mangled_storage_impl::get_function(const std::string &name) const
|
||||
{
|
||||
namespace x3 = spirit::x3;
|
||||
using namespace parser;
|
||||
using func_type = Func*;
|
||||
using return_type = typename function_traits<Func>::result_type;
|
||||
std::string return_type_name = get_name<return_type>();
|
||||
|
||||
|
||||
auto matcher =
|
||||
-(visibility >> static_ >> x3::space) >> //it may be a static class-member, which does however not have the static attribute.
|
||||
parser::type_rule<return_type>(return_type_name) >> x3::space >>
|
||||
cdecl_ >> //cdecl declaration for methods. stdcall cannot be
|
||||
name >> x3::lit('(') >> parser::arg_list(*this, func_type()) >> x3::lit(')') >> parser::ptr_rule();
|
||||
|
||||
|
||||
auto predicate = [&](const mangled_storage_base::entry & e)
|
||||
{
|
||||
if (e.demangled == name)//maybe not mangled,
|
||||
return true;
|
||||
|
||||
auto itr = e.demangled.begin();
|
||||
auto end = e.demangled.end();
|
||||
auto res = x3::parse(itr, end, matcher);
|
||||
|
||||
return res && (itr == end);
|
||||
};
|
||||
|
||||
auto found = std::find_if(storage_.begin(), storage_.end(), predicate);
|
||||
template<typename Func>
|
||||
std::string mangled_storage_impl::get_function(const std::string &name) const {
|
||||
const auto found = std::find_if(storage_.begin(), storage_.end(), parser::is_function_with_name<Func*>(name, *this));
|
||||
|
||||
if (found != storage_.end())
|
||||
return found->mangled;
|
||||
else
|
||||
return "";
|
||||
|
||||
}
|
||||
|
||||
template<typename Class, typename Func>
|
||||
std::string mangled_storage_impl::get_mem_fn(const std::string &name) const
|
||||
{
|
||||
namespace x3 = spirit::x3;
|
||||
using namespace parser;
|
||||
using func_type = Func*;
|
||||
using return_type = typename function_traits<Func>::result_type;
|
||||
auto return_type_name = get_name<return_type>();
|
||||
|
||||
|
||||
auto cname = get_name<Class>();
|
||||
|
||||
auto matcher =
|
||||
visibility >> -virtual_ >> x3::space >>
|
||||
parser::type_rule<return_type>(return_type_name) >> x3::space >>
|
||||
thiscall >> //cdecl declaration for methods. stdcall cannot be
|
||||
cname >> "::" >> name >>
|
||||
x3::lit('(') >> parser::arg_list(*this, func_type()) >> x3::lit(')') >>
|
||||
inv_const_rule<Class>() >> inv_volatile_rule<Class>() >> parser::ptr_rule();
|
||||
|
||||
auto predicate = [&](const mangled_storage_base::entry & e)
|
||||
{
|
||||
auto itr = e.demangled.begin();
|
||||
auto end = e.demangled.end();
|
||||
auto res = x3::parse(itr, end, matcher);
|
||||
|
||||
return res && (itr == end);
|
||||
};
|
||||
|
||||
auto found = std::find_if(storage_.begin(), storage_.end(), predicate);
|
||||
std::string mangled_storage_impl::get_mem_fn(const std::string &name) const {
|
||||
const auto found = std::find_if(storage_.begin(), storage_.end(), parser::is_mem_fn_with_name<Class, Func*>(name, *this));
|
||||
|
||||
if (found != storage_.end())
|
||||
return found->mangled;
|
||||
@@ -304,14 +354,7 @@ std::string mangled_storage_impl::get_mem_fn(const std::string &name) const
|
||||
|
||||
|
||||
template<typename Signature>
|
||||
auto mangled_storage_impl::get_constructor() const -> ctor_sym
|
||||
{
|
||||
namespace x3 = spirit::x3;
|
||||
using namespace parser;
|
||||
|
||||
using func_type = Signature*;
|
||||
|
||||
|
||||
auto mangled_storage_impl::get_constructor() const -> ctor_sym {
|
||||
std::string ctor_name; // = class_name + "::" + name;
|
||||
std::string unscoped_cname; //the unscoped class-name
|
||||
{
|
||||
@@ -329,23 +372,7 @@ auto mangled_storage_impl::get_constructor() const -> ctor_sym
|
||||
}
|
||||
}
|
||||
|
||||
auto matcher =
|
||||
visibility >> x3::space >>
|
||||
thiscall >> //cdecl declaration for methods. stdcall cannot be
|
||||
ctor_name >>
|
||||
x3::lit('(') >> parser::arg_list(*this, func_type()) >> x3::lit(')') >> parser::ptr_rule();
|
||||
|
||||
|
||||
auto predicate = [&](const mangled_storage_base::entry & e)
|
||||
{
|
||||
auto itr = e.demangled.begin();
|
||||
auto end = e.demangled.end();
|
||||
auto res = x3::parse(itr, end, matcher);
|
||||
|
||||
return res && (itr == end);
|
||||
};
|
||||
|
||||
auto f = std::find_if(storage_.begin(), storage_.end(), predicate);
|
||||
const auto f = std::find_if(storage_.begin(), storage_.end(), parser::is_constructor_with_name<Signature*>(ctor_name, *this));
|
||||
|
||||
if (f != storage_.end())
|
||||
return f->mangled;
|
||||
@@ -354,10 +381,7 @@ auto mangled_storage_impl::get_constructor() const -> ctor_sym
|
||||
}
|
||||
|
||||
template<typename Class>
|
||||
auto mangled_storage_impl::get_destructor() const -> dtor_sym
|
||||
{
|
||||
namespace x3 = spirit::x3;
|
||||
using namespace parser;
|
||||
auto mangled_storage_impl::get_destructor() const -> dtor_sym {
|
||||
std::string dtor_name; // = class_name + "::" + name;
|
||||
std::string unscoped_cname; //the unscoped class-name
|
||||
{
|
||||
@@ -375,23 +399,7 @@ auto mangled_storage_impl::get_destructor() const -> dtor_sym
|
||||
}
|
||||
}
|
||||
|
||||
auto matcher =
|
||||
visibility >> -virtual_ >> x3::space >>
|
||||
thiscall >> //cdecl declaration for methods. stdcall cannot be
|
||||
dtor_name >> parser::ptr_rule();
|
||||
|
||||
|
||||
auto predicate = [&](const mangled_storage_base::entry & e)
|
||||
{
|
||||
auto itr = e.demangled.begin();
|
||||
auto end = e.demangled.end();
|
||||
auto res = x3::parse(itr, end, matcher);
|
||||
|
||||
return res && (itr == end);
|
||||
};
|
||||
|
||||
auto found = std::find_if(storage_.begin(), storage_.end(), predicate);
|
||||
|
||||
const auto found = std::find_if(storage_.begin(), storage_.end(), parser::is_destructor_with_name(dtor_name));
|
||||
|
||||
if (found != storage_.end())
|
||||
return found->mangled;
|
||||
@@ -400,8 +408,7 @@ auto mangled_storage_impl::get_destructor() const -> dtor_sym
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
std::string mangled_storage_impl::get_vtable() const
|
||||
{
|
||||
std::string mangled_storage_impl::get_vtable() const {
|
||||
std::string id = "const " + get_name<T>() + "::`vftable'";
|
||||
|
||||
auto predicate = [&](const mangled_storage_base::entry & e)
|
||||
@@ -419,8 +426,7 @@ std::string mangled_storage_impl::get_vtable() const
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
std::vector<std::string> mangled_storage_impl::get_related() const
|
||||
{
|
||||
std::vector<std::string> mangled_storage_impl::get_related() const {
|
||||
std::vector<std::string> ret;
|
||||
auto name = get_name<T>();
|
||||
|
||||
@@ -433,9 +439,6 @@ std::vector<std::string> mangled_storage_impl::get_related() const
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
}}}
|
||||
|
||||
|
||||
|
||||
#endif /* BOOST_DLL_DETAIL_DEMANGLING_MSVC_HPP_ */
|
||||
|
||||
@@ -259,7 +259,7 @@ private:
|
||||
read_raw(fs, symbols[0], static_cast<std::size_t>(symtab_size - (symtab_size % sizeof(symbol_t))) );
|
||||
}
|
||||
|
||||
static bool is_visible(const symbol_t& sym) BOOST_NOEXCEPT {
|
||||
static bool is_visible(const symbol_t& sym) noexcept {
|
||||
const unsigned char visibility = (sym.st_other & 0x03);
|
||||
// `(sym.st_info >> 4) != STB_LOCAL_ && !!sym.st_size` check also workarounds the
|
||||
// GCC's issue https://sourceware.org/bugzilla/show_bug.cgi?id=13621
|
||||
|
||||
@@ -8,11 +8,7 @@
|
||||
#define BOOST_DLL_DETAIL_IMPORT_MANGLED_HELPERS_HPP_
|
||||
|
||||
|
||||
#include <boost/type_traits/conditional.hpp>
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
#include <boost/type_traits/is_class.hpp>
|
||||
#include <boost/type_traits/is_function.hpp>
|
||||
#include <boost/type_traits/remove_cv.hpp>
|
||||
#include <type_traits>
|
||||
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
@@ -34,9 +30,9 @@ struct push_front<Value, sequence<Args...>>
|
||||
|
||||
template<class Lhs, class Rhs>
|
||||
struct unqalified_is_same :
|
||||
boost::is_same<
|
||||
typename boost::remove_cv<Lhs>::type,
|
||||
typename boost::remove_cv<Rhs>::type
|
||||
std::is_same<
|
||||
typename std::remove_cv<Lhs>::type,
|
||||
typename std::remove_cv<Rhs>::type
|
||||
>
|
||||
{
|
||||
};
|
||||
@@ -48,19 +44,19 @@ template<class T> struct is_function_seq;
|
||||
|
||||
//type-trait for function overloads
|
||||
template<class Class, class...Args> struct is_function_seq<sequence<Class, Args...>>
|
||||
: boost::conditional<
|
||||
boost::is_function<Class>::value,
|
||||
: std::conditional<
|
||||
std::is_function<Class>::value,
|
||||
is_function_seq<sequence<Args...>>,
|
||||
boost::false_type>::type
|
||||
std::false_type>::type
|
||||
{};
|
||||
|
||||
template<class Class>
|
||||
struct is_function_seq<sequence<Class>> : boost::is_function<Class>
|
||||
struct is_function_seq<sequence<Class>> : std::is_function<Class>
|
||||
{
|
||||
};
|
||||
|
||||
template<>
|
||||
struct is_function_seq<sequence<>> : boost::false_type
|
||||
struct is_function_seq<sequence<>> : std::false_type
|
||||
{
|
||||
};
|
||||
|
||||
@@ -151,11 +147,11 @@ struct make_mem_fn_seq<T0, T1, T2, Args...>
|
||||
* Class, const Class, void(int)//--> ovl class.
|
||||
*
|
||||
*/
|
||||
static_assert(boost::is_object<T0>::value, "");
|
||||
static_assert(std::is_object<T0>::value, "");
|
||||
typedef typename make_mem_fn_seq_getter<
|
||||
unqalified_is_same<T0, T1>::value, T0, T1, T2>::type mem_fn_type;
|
||||
|
||||
typedef typename boost::conditional<
|
||||
typedef typename std::conditional<
|
||||
unqalified_is_same<T0, T1>::value,
|
||||
make_mem_fn_seq<T1, Args...>,
|
||||
make_mem_fn_seq<T0, T2, Args...>> ::type next;
|
||||
@@ -203,46 +199,46 @@ struct make_mem_fn_seq<T0, T1, T2, Args...>
|
||||
template<class T, class U, class ...Args>
|
||||
struct is_mem_fn_seq_impl
|
||||
{
|
||||
typedef typename boost::conditional<
|
||||
boost::is_function<U>::value || boost::dll::experimental::detail::unqalified_is_same<T, U>::value,
|
||||
typedef typename std::conditional<
|
||||
std::is_function<U>::value || boost::dll::experimental::detail::unqalified_is_same<T, U>::value,
|
||||
typename is_mem_fn_seq_impl<T, Args...>::type,
|
||||
boost::false_type>::type type;
|
||||
std::false_type>::type type;
|
||||
};
|
||||
|
||||
template<class T, class U>
|
||||
struct is_mem_fn_seq_impl<T, U>
|
||||
{
|
||||
typedef typename boost::conditional<
|
||||
boost::is_function<U>::value && boost::is_object<T>::value,
|
||||
boost::true_type, boost::false_type>::type type;
|
||||
typedef typename std::conditional<
|
||||
std::is_function<U>::value && std::is_object<T>::value,
|
||||
std::true_type, std::false_type>::type type;
|
||||
};
|
||||
|
||||
template<class T, class U, class Last>
|
||||
struct is_mem_fn_seq_impl<T, U, Last>
|
||||
{
|
||||
typedef typename boost::conditional<
|
||||
(boost::is_function<U>::value || boost::dll::experimental::detail::unqalified_is_same<T, U>::value)
|
||||
&& boost::is_function<Last>::value,
|
||||
boost::true_type, boost::false_type>::type type;
|
||||
typedef typename std::conditional<
|
||||
(std::is_function<U>::value || boost::dll::experimental::detail::unqalified_is_same<T, U>::value)
|
||||
&& std::is_function<Last>::value,
|
||||
std::true_type, std::false_type>::type type;
|
||||
};
|
||||
|
||||
template<class T> struct is_mem_fn_seq : boost::false_type {};
|
||||
template<class T> struct is_mem_fn_seq : std::false_type {};
|
||||
|
||||
//If only two arguments are provided at all.
|
||||
template<class T, class U>
|
||||
struct is_mem_fn_seq<sequence<T, U>> : boost::conditional<
|
||||
boost::is_object<T>::value && boost::is_function<U>::value,
|
||||
boost::true_type, boost::false_type>::type
|
||||
struct is_mem_fn_seq<sequence<T, U>> : std::conditional<
|
||||
std::is_object<T>::value && std::is_function<U>::value,
|
||||
std::true_type, std::false_type>::type
|
||||
{
|
||||
};
|
||||
|
||||
|
||||
template<class T, class Func, class ...Args>
|
||||
struct is_mem_fn_seq<sequence<T, Func, Args...>> :
|
||||
boost::conditional<
|
||||
boost::is_class<T>::value && boost::is_function<Func>::value,
|
||||
std::conditional<
|
||||
std::is_class<T>::value && std::is_function<Func>::value,
|
||||
typename is_mem_fn_seq_impl<T, Args...>::type,
|
||||
boost::false_type>::type {};
|
||||
std::false_type>::type {};
|
||||
|
||||
|
||||
/* ********************************** mem fn sequence tuple ******************************/
|
||||
|
||||
@@ -350,6 +350,9 @@ public:
|
||||
// getting ordinal
|
||||
fs.seekg(fixed_ordinals_addr + i * sizeof(ordinal));
|
||||
read_raw(fs, ordinal);
|
||||
if (ordinal >= exported_symbols) { // required for clang-win created PE
|
||||
continue;
|
||||
}
|
||||
|
||||
// getting function addr
|
||||
fs.seekg(fixed_functions_addr + ordinal * sizeof(ptr));
|
||||
@@ -380,7 +383,7 @@ public:
|
||||
MSVCR110D.dll
|
||||
*/
|
||||
/*
|
||||
static std::vector<std::string> depend_of(boost::dll::fs::error_code &ec) BOOST_NOEXCEPT {
|
||||
static std::vector<std::string> depend_of(boost::dll::fs::error_code &ec) noexcept {
|
||||
std::vector<std::string> ret;
|
||||
|
||||
IMAGE_DOS_HEADER* image_dos_header = (IMAGE_DOS_HEADER*)native();
|
||||
|
||||
@@ -24,13 +24,13 @@
|
||||
# include <cstddef> // for std::ptrdiff_t
|
||||
|
||||
namespace boost { namespace dll { namespace detail {
|
||||
inline void* strip_handle(void* handle) BOOST_NOEXCEPT {
|
||||
inline void* strip_handle(void* handle) noexcept {
|
||||
return reinterpret_cast<void*>(
|
||||
(reinterpret_cast<std::ptrdiff_t>(handle) >> 2) << 2
|
||||
);
|
||||
}
|
||||
|
||||
inline boost::dll::fs::path path_from_handle(void* handle, boost::dll::fs::error_code &ec) {
|
||||
inline boost::dll::fs::path path_from_handle(void* handle, std::error_code &ec) {
|
||||
handle = strip_handle(handle);
|
||||
|
||||
// Iterate through all images currently in memory
|
||||
@@ -53,8 +53,8 @@ namespace boost { namespace dll { namespace detail {
|
||||
}
|
||||
|
||||
boost::dll::detail::reset_dlerror();
|
||||
ec = boost::dll::fs::make_error_code(
|
||||
boost::dll::fs::errc::bad_file_descriptor
|
||||
ec = std::make_error_code(
|
||||
std::errc::bad_file_descriptor
|
||||
);
|
||||
|
||||
return boost::dll::fs::path();
|
||||
@@ -78,7 +78,7 @@ namespace boost { namespace dll { namespace detail {
|
||||
// ... // Ignoring remaning parts of the structure
|
||||
};
|
||||
|
||||
inline boost::dll::fs::path path_from_handle(const void* handle, boost::dll::fs::error_code &ec) {
|
||||
inline boost::dll::fs::path path_from_handle(const void* handle, std::error_code &ec) {
|
||||
static const std::size_t work_around_b_24465209__offset = 128;
|
||||
const struct soinfo* si = reinterpret_cast<const struct soinfo*>(
|
||||
static_cast<const char*>(handle) + work_around_b_24465209__offset
|
||||
@@ -119,7 +119,7 @@ namespace boost { namespace dll { namespace detail {
|
||||
};
|
||||
#endif // #if BOOST_OS_QNX
|
||||
|
||||
inline boost::dll::fs::path path_from_handle(void* handle, boost::dll::fs::error_code &ec) {
|
||||
inline boost::dll::fs::path path_from_handle(void* handle, std::error_code &ec) {
|
||||
// RTLD_DI_LINKMAP (RTLD_DI_ORIGIN returns only folder and is not suitable for this case)
|
||||
// Obtain the Link_map for the handle that is specified.
|
||||
// The p argument points to a Link_map pointer (Link_map
|
||||
@@ -144,8 +144,8 @@ namespace boost { namespace dll { namespace detail {
|
||||
#endif
|
||||
if (!link_map) {
|
||||
boost::dll::detail::reset_dlerror();
|
||||
ec = boost::dll::fs::make_error_code(
|
||||
boost::dll::fs::errc::bad_file_descriptor
|
||||
ec = std::make_error_code(
|
||||
std::errc::bad_file_descriptor
|
||||
);
|
||||
|
||||
return boost::dll::fs::path();
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
#include <mach-o/dyld.h>
|
||||
|
||||
namespace boost { namespace dll { namespace detail {
|
||||
inline boost::dll::fs::path program_location_impl(boost::dll::fs::error_code &ec) {
|
||||
inline boost::dll::fs::path program_location_impl(std::error_code &ec) {
|
||||
ec.clear();
|
||||
|
||||
char path[1024];
|
||||
@@ -31,8 +31,8 @@ namespace boost { namespace dll { namespace detail {
|
||||
|
||||
char *p = new char[size];
|
||||
if (_NSGetExecutablePath(p, &size) != 0) {
|
||||
ec = boost::dll::fs::make_error_code(
|
||||
boost::dll::fs::errc::bad_file_descriptor
|
||||
ec = std::make_error_code(
|
||||
std::errc::bad_file_descriptor
|
||||
);
|
||||
}
|
||||
|
||||
@@ -46,7 +46,7 @@ namespace boost { namespace dll { namespace detail {
|
||||
|
||||
#include <stdlib.h>
|
||||
namespace boost { namespace dll { namespace detail {
|
||||
inline boost::dll::fs::path program_location_impl(boost::dll::fs::error_code& ec) {
|
||||
inline boost::dll::fs::path program_location_impl(std::error_code& ec) {
|
||||
ec.clear();
|
||||
|
||||
return boost::dll::fs::path(getexecname());
|
||||
@@ -60,7 +60,7 @@ namespace boost { namespace dll { namespace detail {
|
||||
#include <stdlib.h>
|
||||
|
||||
namespace boost { namespace dll { namespace detail {
|
||||
inline boost::dll::fs::path program_location_impl(boost::dll::fs::error_code& ec) {
|
||||
inline boost::dll::fs::path program_location_impl(std::error_code& ec) {
|
||||
ec.clear();
|
||||
|
||||
int mib[4];
|
||||
@@ -81,7 +81,7 @@ namespace boost { namespace dll { namespace detail {
|
||||
#elif BOOST_OS_BSD_NET
|
||||
|
||||
namespace boost { namespace dll { namespace detail {
|
||||
inline boost::dll::fs::path program_location_impl(boost::dll::fs::error_code &ec) {
|
||||
inline boost::dll::fs::path program_location_impl(std::error_code &ec) {
|
||||
return boost::dll::fs::read_symlink("/proc/curproc/exe", ec);
|
||||
}
|
||||
}}} // namespace boost::dll::detail
|
||||
@@ -90,7 +90,7 @@ namespace boost { namespace dll { namespace detail {
|
||||
|
||||
|
||||
namespace boost { namespace dll { namespace detail {
|
||||
inline boost::dll::fs::path program_location_impl(boost::dll::fs::error_code &ec) {
|
||||
inline boost::dll::fs::path program_location_impl(std::error_code &ec) {
|
||||
return boost::dll::fs::read_symlink("/proc/curproc/file", ec);
|
||||
}
|
||||
}}} // namespace boost::dll::detail
|
||||
@@ -100,7 +100,7 @@ namespace boost { namespace dll { namespace detail {
|
||||
#include <fstream>
|
||||
#include <string> // for std::getline
|
||||
namespace boost { namespace dll { namespace detail {
|
||||
inline boost::dll::fs::path program_location_impl(boost::dll::fs::error_code &ec) {
|
||||
inline boost::dll::fs::path program_location_impl(std::error_code &ec) {
|
||||
ec.clear();
|
||||
|
||||
std::string s;
|
||||
@@ -108,8 +108,8 @@ namespace boost { namespace dll { namespace detail {
|
||||
std::getline(ifs, s);
|
||||
|
||||
if (ifs.fail() || s.empty()) {
|
||||
ec = boost::dll::fs::make_error_code(
|
||||
boost::dll::fs::errc::bad_file_descriptor
|
||||
ec = std::make_error_code(
|
||||
std::errc::bad_file_descriptor
|
||||
);
|
||||
}
|
||||
|
||||
@@ -120,12 +120,15 @@ namespace boost { namespace dll { namespace detail {
|
||||
#else // BOOST_OS_LINUX || BOOST_OS_UNIX || BOOST_OS_HPUX || BOOST_OS_ANDROID
|
||||
|
||||
namespace boost { namespace dll { namespace detail {
|
||||
inline boost::dll::fs::path program_location_impl(boost::dll::fs::error_code &ec) {
|
||||
inline boost::dll::fs::path program_location_impl(std::error_code &ec) {
|
||||
// We can not use
|
||||
// boost::dll::detail::path_from_handle(dlopen(NULL, RTLD_LAZY | RTLD_LOCAL), ignore);
|
||||
// because such code returns empty path.
|
||||
|
||||
return boost::dll::fs::read_symlink("/proc/self/exe", ec); // Linux specific
|
||||
boost::dll::fs::error_code fs_errc;
|
||||
auto result = boost::dll::fs::read_symlink("/proc/self/exe", fs_errc); // Linux specific
|
||||
ec = fs_errc;
|
||||
return result;
|
||||
}
|
||||
}}} // namespace boost::dll::detail
|
||||
|
||||
|
||||
@@ -13,10 +13,11 @@
|
||||
#include <boost/dll/detail/posix/path_from_handle.hpp>
|
||||
#include <boost/dll/detail/posix/program_location_impl.hpp>
|
||||
|
||||
#include <boost/move/utility.hpp>
|
||||
#include <boost/core/invoke_swap.hpp>
|
||||
#include <boost/predef/os.h>
|
||||
|
||||
#include <utility> // std::move
|
||||
|
||||
#include <dlfcn.h>
|
||||
#include <cstring> // strncmp
|
||||
#if !BOOST_OS_MACOS && !BOOST_OS_IOS && !BOOST_OS_QNX
|
||||
@@ -33,31 +34,28 @@
|
||||
namespace boost { namespace dll { namespace detail {
|
||||
|
||||
class shared_library_impl {
|
||||
|
||||
BOOST_MOVABLE_BUT_NOT_COPYABLE(shared_library_impl)
|
||||
|
||||
public:
|
||||
typedef void* native_handle_t;
|
||||
|
||||
shared_library_impl() BOOST_NOEXCEPT
|
||||
: handle_(NULL)
|
||||
shared_library_impl() noexcept
|
||||
: handle_(nullptr)
|
||||
{}
|
||||
|
||||
~shared_library_impl() BOOST_NOEXCEPT {
|
||||
~shared_library_impl() noexcept {
|
||||
unload();
|
||||
}
|
||||
|
||||
shared_library_impl(BOOST_RV_REF(shared_library_impl) sl) BOOST_NOEXCEPT
|
||||
shared_library_impl(shared_library_impl&& sl) noexcept
|
||||
: handle_(sl.handle_)
|
||||
{
|
||||
sl.handle_ = NULL;
|
||||
sl.handle_ = nullptr;
|
||||
}
|
||||
|
||||
shared_library_impl(native_handle_t handle)
|
||||
explicit shared_library_impl(native_handle_t handle) noexcept
|
||||
: handle_(handle)
|
||||
{}
|
||||
|
||||
shared_library_impl & operator=(BOOST_RV_REF(shared_library_impl) sl) BOOST_NOEXCEPT {
|
||||
shared_library_impl & operator=(shared_library_impl&& sl) noexcept {
|
||||
swap(sl);
|
||||
return *this;
|
||||
}
|
||||
@@ -73,7 +71,7 @@ public:
|
||||
return actual_path;
|
||||
}
|
||||
|
||||
void load(boost::dll::fs::path sl, load_mode::type portable_mode, boost::dll::fs::error_code &ec) {
|
||||
void load(boost::dll::fs::path sl, load_mode::type portable_mode, std::error_code &ec) {
|
||||
typedef int native_mode_t;
|
||||
native_mode_t native_mode = static_cast<native_mode_t>(portable_mode);
|
||||
unload();
|
||||
@@ -81,8 +79,8 @@ public:
|
||||
// Do not allow opening NULL paths. User must use program_location() instead
|
||||
if (sl.empty()) {
|
||||
boost::dll::detail::reset_dlerror();
|
||||
ec = boost::dll::fs::make_error_code(
|
||||
boost::dll::fs::errc::bad_file_descriptor
|
||||
ec = std::make_error_code(
|
||||
std::errc::bad_file_descriptor
|
||||
);
|
||||
|
||||
return;
|
||||
@@ -128,8 +126,8 @@ public:
|
||||
boost::dll::fs::path loc = boost::dll::detail::program_location_impl(prog_loc_err);
|
||||
if (boost::dll::fs::exists(actual_path) && !boost::dll::fs::equivalent(sl, loc, prog_loc_err)) {
|
||||
// decorated path exists : current error is not a bad file descriptor and we are not trying to load the executable itself
|
||||
ec = boost::dll::fs::make_error_code(
|
||||
boost::dll::fs::errc::executable_format_error
|
||||
ec = std::make_error_code(
|
||||
std::errc::executable_format_error
|
||||
);
|
||||
return;
|
||||
}
|
||||
@@ -142,8 +140,8 @@ public:
|
||||
return;
|
||||
}
|
||||
|
||||
ec = boost::dll::fs::make_error_code(
|
||||
boost::dll::fs::errc::bad_file_descriptor
|
||||
ec = std::make_error_code(
|
||||
std::errc::bad_file_descriptor
|
||||
);
|
||||
|
||||
// Maybe user wanted to load the executable itself? Checking...
|
||||
@@ -158,20 +156,20 @@ public:
|
||||
// returned handle is for the main program.
|
||||
ec.clear();
|
||||
boost::dll::detail::reset_dlerror();
|
||||
handle_ = dlopen(NULL, native_mode);
|
||||
handle_ = dlopen(nullptr, native_mode);
|
||||
if (!handle_) {
|
||||
ec = boost::dll::fs::make_error_code(
|
||||
boost::dll::fs::errc::bad_file_descriptor
|
||||
ec = std::make_error_code(
|
||||
std::errc::bad_file_descriptor
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool is_loaded() const BOOST_NOEXCEPT {
|
||||
bool is_loaded() const noexcept {
|
||||
return (handle_ != 0);
|
||||
}
|
||||
|
||||
void unload() BOOST_NOEXCEPT {
|
||||
void unload() noexcept {
|
||||
if (!is_loaded()) {
|
||||
return;
|
||||
}
|
||||
@@ -180,11 +178,11 @@ public:
|
||||
handle_ = 0;
|
||||
}
|
||||
|
||||
void swap(shared_library_impl& rhs) BOOST_NOEXCEPT {
|
||||
void swap(shared_library_impl& rhs) noexcept {
|
||||
boost::core::invoke_swap(handle_, rhs.handle_);
|
||||
}
|
||||
|
||||
boost::dll::fs::path full_module_path(boost::dll::fs::error_code &ec) const {
|
||||
boost::dll::fs::path full_module_path(std::error_code &ec) const {
|
||||
return boost::dll::detail::path_from_handle(handle_, ec);
|
||||
}
|
||||
|
||||
@@ -197,12 +195,12 @@ public:
|
||||
#endif
|
||||
}
|
||||
|
||||
void* symbol_addr(const char* sb, boost::dll::fs::error_code &ec) const BOOST_NOEXCEPT {
|
||||
void* symbol_addr(const char* sb, std::error_code &ec) const noexcept {
|
||||
// dlsym - obtain the address of a symbol from a dlopen object
|
||||
void* const symbol = dlsym(handle_, sb);
|
||||
if (symbol == NULL) {
|
||||
ec = boost::dll::fs::make_error_code(
|
||||
boost::dll::fs::errc::invalid_seek
|
||||
if (symbol == nullptr) {
|
||||
ec = std::make_error_code(
|
||||
std::errc::invalid_seek
|
||||
);
|
||||
}
|
||||
|
||||
@@ -214,7 +212,7 @@ public:
|
||||
return symbol;
|
||||
}
|
||||
|
||||
native_handle_t native() const BOOST_NOEXCEPT {
|
||||
native_handle_t native() const noexcept {
|
||||
return handle_;
|
||||
}
|
||||
|
||||
|
||||
@@ -22,14 +22,14 @@
|
||||
|
||||
namespace boost { namespace dll { namespace detail {
|
||||
|
||||
inline void reset_dlerror() BOOST_NOEXCEPT {
|
||||
inline void reset_dlerror() noexcept {
|
||||
#if !BOOST_OS_WINDOWS
|
||||
const char* const error_txt = dlerror();
|
||||
(void)error_txt;
|
||||
#endif
|
||||
}
|
||||
|
||||
inline void report_error(const boost::dll::fs::error_code& ec, const char* message) {
|
||||
inline void report_error(const std::error_code& ec, const char* message) {
|
||||
#if !BOOST_OS_WINDOWS
|
||||
const char* const error_txt = dlerror();
|
||||
if (error_txt) {
|
||||
|
||||
@@ -19,15 +19,15 @@
|
||||
|
||||
namespace boost { namespace dll { namespace detail {
|
||||
|
||||
inline boost::dll::fs::error_code last_error_code() BOOST_NOEXCEPT {
|
||||
inline std::error_code last_error_code() noexcept {
|
||||
boost::winapi::DWORD_ err = boost::winapi::GetLastError();
|
||||
return boost::dll::fs::error_code(
|
||||
return std::error_code(
|
||||
static_cast<int>(err),
|
||||
boost::dll::fs::system_category()
|
||||
std::system_category()
|
||||
);
|
||||
}
|
||||
|
||||
inline boost::dll::fs::path path_from_handle(boost::winapi::HMODULE_ handle, boost::dll::fs::error_code &ec) {
|
||||
inline boost::dll::fs::path path_from_handle(boost::winapi::HMODULE_ handle, std::error_code &ec) {
|
||||
BOOST_STATIC_CONSTANT(boost::winapi::DWORD_, ERROR_INSUFFICIENT_BUFFER_ = 0x7A);
|
||||
BOOST_STATIC_CONSTANT(boost::winapi::DWORD_, DEFAULT_PATH_SIZE_ = 260);
|
||||
|
||||
|
||||
@@ -14,11 +14,12 @@
|
||||
#include <boost/dll/detail/system_error.hpp>
|
||||
#include <boost/dll/detail/windows/path_from_handle.hpp>
|
||||
|
||||
#include <boost/move/utility.hpp>
|
||||
#include <boost/core/invoke_swap.hpp>
|
||||
|
||||
#include <boost/winapi/dll.hpp>
|
||||
|
||||
#include <utility> // std::move
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
# pragma once
|
||||
#endif
|
||||
@@ -26,30 +27,28 @@
|
||||
namespace boost { namespace dll { namespace detail {
|
||||
|
||||
class shared_library_impl {
|
||||
BOOST_MOVABLE_BUT_NOT_COPYABLE(shared_library_impl)
|
||||
|
||||
public:
|
||||
typedef boost::winapi::HMODULE_ native_handle_t;
|
||||
|
||||
shared_library_impl() BOOST_NOEXCEPT
|
||||
: handle_(NULL)
|
||||
shared_library_impl() noexcept
|
||||
: shared_library_impl(nullptr)
|
||||
{}
|
||||
|
||||
~shared_library_impl() BOOST_NOEXCEPT {
|
||||
~shared_library_impl() noexcept {
|
||||
unload();
|
||||
}
|
||||
|
||||
shared_library_impl(BOOST_RV_REF(shared_library_impl) sl) BOOST_NOEXCEPT
|
||||
shared_library_impl(shared_library_impl&& sl) noexcept
|
||||
: handle_(sl.handle_)
|
||||
{
|
||||
sl.handle_ = NULL;
|
||||
sl.handle_ = nullptr;
|
||||
}
|
||||
|
||||
shared_library_impl(native_handle_t handle)
|
||||
explicit shared_library_impl(native_handle_t handle) noexcept
|
||||
: handle_(handle)
|
||||
{}
|
||||
|
||||
shared_library_impl & operator=(BOOST_RV_REF(shared_library_impl) sl) BOOST_NOEXCEPT {
|
||||
shared_library_impl & operator=(shared_library_impl&& sl) noexcept {
|
||||
swap(sl);
|
||||
return *this;
|
||||
}
|
||||
@@ -60,7 +59,7 @@ public:
|
||||
return actual_path;
|
||||
}
|
||||
|
||||
void load(boost::dll::fs::path sl, load_mode::type portable_mode, boost::dll::fs::error_code &ec) {
|
||||
void load(boost::dll::fs::path sl, load_mode::type portable_mode, std::error_code &ec) {
|
||||
typedef boost::winapi::DWORD_ native_mode_t;
|
||||
native_mode_t native_mode = static_cast<native_mode_t>(portable_mode);
|
||||
unload();
|
||||
@@ -115,22 +114,22 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
bool is_loaded() const BOOST_NOEXCEPT {
|
||||
bool is_loaded() const noexcept {
|
||||
return (handle_ != 0);
|
||||
}
|
||||
|
||||
void unload() BOOST_NOEXCEPT {
|
||||
void unload() noexcept {
|
||||
if (handle_) {
|
||||
boost::winapi::FreeLibrary(handle_);
|
||||
handle_ = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void swap(shared_library_impl& rhs) BOOST_NOEXCEPT {
|
||||
void swap(shared_library_impl& rhs) noexcept {
|
||||
boost::core::invoke_swap(handle_, rhs.handle_);
|
||||
}
|
||||
|
||||
boost::dll::fs::path full_module_path(boost::dll::fs::error_code &ec) const {
|
||||
boost::dll::fs::path full_module_path(std::error_code &ec) const {
|
||||
return boost::dll::detail::path_from_handle(handle_, ec);
|
||||
}
|
||||
|
||||
@@ -138,16 +137,16 @@ public:
|
||||
return L".dll";
|
||||
}
|
||||
|
||||
void* symbol_addr(const char* sb, boost::dll::fs::error_code &ec) const BOOST_NOEXCEPT {
|
||||
void* symbol_addr(const char* sb, std::error_code &ec) const noexcept {
|
||||
if (is_resource()) {
|
||||
// `GetProcAddress` could not be called for libraries loaded with
|
||||
// `LOAD_LIBRARY_AS_DATAFILE`, `LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE`
|
||||
// or `LOAD_LIBRARY_AS_IMAGE_RESOURCE`.
|
||||
ec = boost::dll::fs::make_error_code(
|
||||
boost::dll::fs::errc::operation_not_supported
|
||||
ec = std::make_error_code(
|
||||
std::errc::operation_not_supported
|
||||
);
|
||||
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Judging by the documentation of GetProcAddress
|
||||
@@ -156,20 +155,20 @@ public:
|
||||
void* const symbol = boost::dll::detail::aggressive_ptr_cast<void*>(
|
||||
boost::winapi::get_proc_address(handle_, sb)
|
||||
);
|
||||
if (symbol == NULL) {
|
||||
if (symbol == nullptr) {
|
||||
ec = boost::dll::detail::last_error_code();
|
||||
}
|
||||
|
||||
return symbol;
|
||||
}
|
||||
|
||||
native_handle_t native() const BOOST_NOEXCEPT {
|
||||
native_handle_t native() const noexcept {
|
||||
return handle_;
|
||||
}
|
||||
|
||||
private:
|
||||
// Returns true if this load attempt should be the last one.
|
||||
bool load_impl(const boost::dll::fs::path &load_path, boost::winapi::DWORD_ mode, boost::dll::fs::error_code &ec) {
|
||||
bool load_impl(const boost::dll::fs::path &load_path, boost::winapi::DWORD_ mode, std::error_code &ec) {
|
||||
handle_ = boost::winapi::LoadLibraryExW(load_path.c_str(), 0, mode);
|
||||
if (handle_) {
|
||||
return true;
|
||||
@@ -185,7 +184,7 @@ private:
|
||||
return false;
|
||||
}
|
||||
|
||||
bool is_resource() const BOOST_NOEXCEPT {
|
||||
bool is_resource() const noexcept {
|
||||
return false; /*!!(
|
||||
reinterpret_cast<boost::winapi::ULONG_PTR_>(handle_) & static_cast<boost::winapi::ULONG_PTR_>(3)
|
||||
);*/
|
||||
|
||||
@@ -9,16 +9,11 @@
|
||||
#define BOOST_DLL_IMPORT_HPP
|
||||
|
||||
#include <boost/dll/config.hpp>
|
||||
#include <boost/core/addressof.hpp>
|
||||
#include <boost/core/enable_if.hpp>
|
||||
#include <boost/type_traits/is_object.hpp>
|
||||
#include <boost/make_shared.hpp>
|
||||
#include <boost/dll/shared_library.hpp>
|
||||
#include <boost/move/move.hpp>
|
||||
|
||||
#if defined(BOOST_NO_CXX11_TRAILING_RESULT_TYPES) || defined(BOOST_NO_CXX11_DECLTYPE) || defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||
# include <boost/function.hpp>
|
||||
#endif
|
||||
#include <memory> // std::addressof
|
||||
#include <type_traits>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
# pragma once
|
||||
@@ -40,16 +35,10 @@ namespace detail {
|
||||
boost::shared_ptr<T> f_;
|
||||
|
||||
public:
|
||||
inline library_function(const boost::shared_ptr<shared_library>& lib, T* func_ptr) BOOST_NOEXCEPT
|
||||
inline library_function(const boost::shared_ptr<shared_library>& lib, T* func_ptr) noexcept
|
||||
: f_(lib, func_ptr)
|
||||
{}
|
||||
|
||||
#if defined(BOOST_NO_CXX11_TRAILING_RESULT_TYPES) || defined(BOOST_NO_CXX11_DECLTYPE) || defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||
operator T*() const BOOST_NOEXCEPT {
|
||||
return f_.get();
|
||||
}
|
||||
#else
|
||||
|
||||
// Compilation error at this point means that imported function
|
||||
// was called with unmatching parameters.
|
||||
//
|
||||
@@ -64,33 +53,20 @@ namespace detail {
|
||||
{
|
||||
return (*f_)(static_cast<Args&&>(args)...);
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
template <class T, class = void>
|
||||
struct import_type;
|
||||
|
||||
template <class T>
|
||||
struct import_type<T, typename boost::disable_if<boost::is_object<T> >::type> {
|
||||
typedef boost::dll::detail::library_function<T> base_type;
|
||||
|
||||
#if defined(BOOST_NO_CXX11_TRAILING_RESULT_TYPES) || defined(BOOST_NO_CXX11_DECLTYPE) || defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||
typedef boost::function<T> type;
|
||||
#else
|
||||
typedef boost::dll::detail::library_function<T> type;
|
||||
#endif
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct import_type<T, typename boost::enable_if<boost::is_object<T> >::type> {
|
||||
typedef boost::shared_ptr<T> base_type;
|
||||
typedef boost::shared_ptr<T> type;
|
||||
};
|
||||
using import_type = typename std::conditional<
|
||||
std::is_object<T>::value,
|
||||
boost::shared_ptr<T>,
|
||||
boost::dll::detail::library_function<T>
|
||||
>::type;
|
||||
} // namespace detail
|
||||
|
||||
|
||||
#ifndef BOOST_DLL_DOXYGEN
|
||||
# define BOOST_DLL_IMPORT_RESULT_TYPE inline typename boost::dll::detail::import_type<T>::type
|
||||
# define BOOST_DLL_IMPORT_RESULT_TYPE inline boost::dll::detail::import_type<T>
|
||||
#endif
|
||||
|
||||
|
||||
@@ -108,7 +84,7 @@ namespace detail {
|
||||
* \b Examples:
|
||||
*
|
||||
* \code
|
||||
* boost::function<int(int)> f = import_symbol<int(int)>("test_lib.so", "integer_func_name");
|
||||
* std::function<int(int)> f = import_symbol<int(int)>("test_lib.so", "integer_func_name");
|
||||
*
|
||||
* auto f_cpp11 = import_symbol<int(int)>("test_lib.so", "integer_func_name");
|
||||
* \endcode
|
||||
@@ -132,10 +108,10 @@ template <class T>
|
||||
BOOST_DLL_IMPORT_RESULT_TYPE import_symbol(const boost::dll::fs::path& lib, const char* name,
|
||||
load_mode::type mode = load_mode::default_mode)
|
||||
{
|
||||
typedef typename boost::dll::detail::import_type<T>::base_type type;
|
||||
using type = boost::dll::detail::import_type<T>;
|
||||
|
||||
boost::shared_ptr<boost::dll::shared_library> p = boost::make_shared<boost::dll::shared_library>(lib, mode);
|
||||
return type(p, boost::addressof(p->get<T>(name)));
|
||||
auto p = boost::make_shared<boost::dll::shared_library>(lib, mode);
|
||||
return type(p, std::addressof(p->get<T>(name)));
|
||||
}
|
||||
|
||||
//! \overload boost::dll::import_symbol(const boost::dll::fs::path& lib, const char* name, load_mode::type mode)
|
||||
@@ -149,10 +125,10 @@ BOOST_DLL_IMPORT_RESULT_TYPE import_symbol(const boost::dll::fs::path& lib, cons
|
||||
//! \overload boost::dll::import_symbol(const boost::dll::fs::path& lib, const char* name, load_mode::type mode)
|
||||
template <class T>
|
||||
BOOST_DLL_IMPORT_RESULT_TYPE import_symbol(const shared_library& lib, const char* name) {
|
||||
typedef typename boost::dll::detail::import_type<T>::base_type type;
|
||||
using type = boost::dll::detail::import_type<T>;
|
||||
|
||||
boost::shared_ptr<boost::dll::shared_library> p = boost::make_shared<boost::dll::shared_library>(lib);
|
||||
return type(p, boost::addressof(p->get<T>(name)));
|
||||
auto p = boost::make_shared<boost::dll::shared_library>(lib);
|
||||
return type(p, std::addressof(p->get<T>(name)));
|
||||
}
|
||||
|
||||
//! \overload boost::dll::import_symbol(const boost::dll::fs::path& lib, const char* name, load_mode::type mode)
|
||||
@@ -163,19 +139,19 @@ BOOST_DLL_IMPORT_RESULT_TYPE import_symbol(const shared_library& lib, const std:
|
||||
|
||||
//! \overload boost::dll::import_symbol(const boost::dll::fs::path& lib, const char* name, load_mode::type mode)
|
||||
template <class T>
|
||||
BOOST_DLL_IMPORT_RESULT_TYPE import_symbol(BOOST_RV_REF(shared_library) lib, const char* name) {
|
||||
typedef typename boost::dll::detail::import_type<T>::base_type type;
|
||||
BOOST_DLL_IMPORT_RESULT_TYPE import_symbol(shared_library&& lib, const char* name) {
|
||||
using type = boost::dll::detail::import_type<T>;
|
||||
|
||||
boost::shared_ptr<boost::dll::shared_library> p = boost::make_shared<boost::dll::shared_library>(
|
||||
boost::move(lib)
|
||||
auto p = boost::make_shared<boost::dll::shared_library>(
|
||||
std::move(lib)
|
||||
);
|
||||
return type(p, boost::addressof(p->get<T>(name)));
|
||||
return type(p, std::addressof(p->get<T>(name)));
|
||||
}
|
||||
|
||||
//! \overload boost::dll::import_symbol(const boost::dll::fs::path& lib, const char* name, load_mode::type mode)
|
||||
template <class T>
|
||||
BOOST_DLL_IMPORT_RESULT_TYPE import_symbol(BOOST_RV_REF(shared_library) lib, const std::string& name) {
|
||||
return dll::import_symbol<T>(boost::move(lib), name.c_str());
|
||||
BOOST_DLL_IMPORT_RESULT_TYPE import_symbol(shared_library&& lib, const std::string& name) {
|
||||
return dll::import_symbol<T>(std::move(lib), name.c_str());
|
||||
}
|
||||
|
||||
|
||||
@@ -195,7 +171,7 @@ BOOST_DLL_IMPORT_RESULT_TYPE import_symbol(BOOST_RV_REF(shared_library) lib, con
|
||||
* \b Examples:
|
||||
*
|
||||
* \code
|
||||
* boost::function<int(int)> f = import_alias<int(int)>("test_lib.so", "integer_func_alias_name");
|
||||
* std::function<int(int)> f = import_alias<int(int)>("test_lib.so", "integer_func_alias_name");
|
||||
*
|
||||
* auto f_cpp11 = import_alias<int(int)>("test_lib.so", "integer_func_alias_name");
|
||||
* \endcode
|
||||
@@ -222,9 +198,9 @@ template <class T>
|
||||
BOOST_DLL_IMPORT_RESULT_TYPE import_alias(const boost::dll::fs::path& lib, const char* name,
|
||||
load_mode::type mode = load_mode::default_mode)
|
||||
{
|
||||
typedef typename boost::dll::detail::import_type<T>::base_type type;
|
||||
using type = boost::dll::detail::import_type<T>;
|
||||
|
||||
boost::shared_ptr<boost::dll::shared_library> p = boost::make_shared<boost::dll::shared_library>(lib, mode);
|
||||
auto p = boost::make_shared<boost::dll::shared_library>(lib, mode);
|
||||
return type(p, p->get<T*>(name));
|
||||
}
|
||||
|
||||
@@ -239,9 +215,9 @@ BOOST_DLL_IMPORT_RESULT_TYPE import_alias(const boost::dll::fs::path& lib, const
|
||||
//! \overload boost::dll::import_alias(const boost::dll::fs::path& lib, const char* name, load_mode::type mode)
|
||||
template <class T>
|
||||
BOOST_DLL_IMPORT_RESULT_TYPE import_alias(const shared_library& lib, const char* name) {
|
||||
typedef typename boost::dll::detail::import_type<T>::base_type type;
|
||||
using type = boost::dll::detail::import_type<T>;
|
||||
|
||||
boost::shared_ptr<boost::dll::shared_library> p = boost::make_shared<boost::dll::shared_library>(lib);
|
||||
auto p = boost::make_shared<boost::dll::shared_library>(lib);
|
||||
return type(p, p->get<T*>(name));
|
||||
}
|
||||
|
||||
@@ -253,19 +229,19 @@ BOOST_DLL_IMPORT_RESULT_TYPE import_alias(const shared_library& lib, const std::
|
||||
|
||||
//! \overload boost::dll::import_alias(const boost::dll::fs::path& lib, const char* name, load_mode::type mode)
|
||||
template <class T>
|
||||
BOOST_DLL_IMPORT_RESULT_TYPE import_alias(BOOST_RV_REF(shared_library) lib, const char* name) {
|
||||
typedef typename boost::dll::detail::import_type<T>::base_type type;
|
||||
BOOST_DLL_IMPORT_RESULT_TYPE import_alias(shared_library&& lib, const char* name) {
|
||||
using type = boost::dll::detail::import_type<T>;
|
||||
|
||||
boost::shared_ptr<boost::dll::shared_library> p = boost::make_shared<boost::dll::shared_library>(
|
||||
boost::move(lib)
|
||||
auto p = boost::make_shared<boost::dll::shared_library>(
|
||||
std::move(lib)
|
||||
);
|
||||
return type(p, p->get<T*>(name));
|
||||
}
|
||||
|
||||
//! \overload boost::dll::import_alias(const boost::dll::fs::path& lib, const char* name, load_mode::type mode)
|
||||
template <class T>
|
||||
BOOST_DLL_IMPORT_RESULT_TYPE import_alias(BOOST_RV_REF(shared_library) lib, const std::string& name) {
|
||||
return dll::import_alias<T>(boost::move(lib), name.c_str());
|
||||
BOOST_DLL_IMPORT_RESULT_TYPE import_alias(shared_library&& lib, const std::string& name) {
|
||||
return dll::import_alias<T>(std::move(lib), name.c_str());
|
||||
}
|
||||
|
||||
#undef BOOST_DLL_IMPORT_RESULT_TYPE
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
#include <boost/dll/smart_library.hpp>
|
||||
#include <boost/dll/import_mangled.hpp>
|
||||
#include <memory>
|
||||
#include <utility> // std::move
|
||||
|
||||
#if (__cplusplus < 201103L) && (!defined(_MSVC_LANG) || _MSVC_LANG < 201103L)
|
||||
# error This file requires C++11 at least!
|
||||
@@ -68,7 +69,7 @@ struct mem_fn_call_proxy<Class, boost::dll::experimental::detail::mangled_librar
|
||||
: t(t), mem_fn(mem_fn) {}
|
||||
|
||||
template<typename ...Args>
|
||||
auto operator()(Args&&...args) const
|
||||
auto operator()(Args&&...args) const -> decltype(mem_fn(t, std::forward<Args>(args)...))
|
||||
{
|
||||
return mem_fn(t, std::forward<Args>(args)...);
|
||||
}
|
||||
@@ -119,11 +120,11 @@ import_class(const smart_library& lib, std::size_t size,
|
||||
template<typename T>
|
||||
class imported_class
|
||||
{
|
||||
smart_library _lib;
|
||||
std::unique_ptr<T, detail::deleter<T>> _data;
|
||||
bool _is_allocating;
|
||||
std::size_t _size;
|
||||
const std::type_info& _ti;
|
||||
smart_library lib_;
|
||||
std::unique_ptr<T, detail::deleter<T>> data_;
|
||||
bool is_allocating_;
|
||||
std::size_t size_;
|
||||
const std::type_info& ti_;
|
||||
|
||||
template<typename ... Args>
|
||||
inline std::unique_ptr<T, detail::deleter<T>> make_data(const smart_library& lib, Args ... args);
|
||||
@@ -147,14 +148,14 @@ public:
|
||||
static imported_class<T> make(smart_library&& lib, Args...args)
|
||||
{
|
||||
typedef detail::sequence<Args...> *seq;
|
||||
return imported_class(seq(), boost::move(lib), static_cast<Args>(args)...);
|
||||
return imported_class(seq(), std::move(lib), static_cast<Args>(args)...);
|
||||
}
|
||||
|
||||
template<typename ...Args>
|
||||
static imported_class<T> make(smart_library&& lib, std::size_t size, Args...args)
|
||||
{
|
||||
typedef detail::sequence<Args...> *seq;
|
||||
return imported_class(seq(), boost::move(lib), size, static_cast<Args>(args)...);
|
||||
return imported_class(seq(), std::move(lib), size, static_cast<Args>(args)...);
|
||||
}
|
||||
template<typename ...Args>
|
||||
static imported_class<T> make(const smart_library& lib, Args...args)
|
||||
@@ -172,7 +173,7 @@ public:
|
||||
|
||||
typedef imported_class<T> base_t;
|
||||
///Returns a pointer to the underlying class
|
||||
T* get() {return _data.get();}
|
||||
T* get() {return data_.get();}
|
||||
imported_class() = delete;
|
||||
|
||||
imported_class(imported_class&) = delete;
|
||||
@@ -181,13 +182,13 @@ public:
|
||||
imported_class& operator=(imported_class&&) = default; ///<Move assignmend
|
||||
|
||||
///Check if the imported class is move-constructible
|
||||
bool is_move_constructible() {return !_lib.symbol_storage().template get_constructor<T(T&&)> ().empty();}
|
||||
bool is_move_constructible() {return !lib_.symbol_storage().template get_constructor<T(T&&)> ().empty();}
|
||||
///Check if the imported class is move-assignable
|
||||
bool is_move_assignable() {return !_lib.symbol_storage().template get_mem_fn<T, T&(T&&)> ("operator=").empty();}
|
||||
bool is_move_assignable() {return !lib_.symbol_storage().template get_mem_fn<T, T&(T&&)> ("operator=").empty();}
|
||||
///Check if the imported class is copy-constructible
|
||||
bool is_copy_constructible() {return !_lib.symbol_storage().template get_constructor<T(const T&)>().empty();}
|
||||
bool is_copy_constructible() {return !lib_.symbol_storage().template get_constructor<T(const T&)>().empty();}
|
||||
///Check if the imported class is copy-assignable
|
||||
bool is_copy_assignable() {return !_lib.symbol_storage().template get_mem_fn<T, T&(const T&)>("operator=").empty();}
|
||||
bool is_copy_assignable() {return !lib_.symbol_storage().template get_mem_fn<T, T&(const T&)>("operator=").empty();}
|
||||
|
||||
imported_class<T> copy() const; ///<Invoke the copy constructor. \attention Undefined behaviour if the imported object is not copy constructible.
|
||||
imported_class<T> move(); ///<Invoke the move constructor. \attention Undefined behaviour if the imported object is not move constructible.
|
||||
@@ -198,10 +199,10 @@ public:
|
||||
void move_assign( imported_class<T> & lhs);
|
||||
|
||||
///Check if the class is loaded.
|
||||
explicit operator bool() const {return _data;}
|
||||
explicit operator bool() const {return data_;}
|
||||
|
||||
///Get a const reference to the std::type_info.
|
||||
const std::type_info& get_type_info() {return _ti;};
|
||||
const std::type_info& get_type_info() {return ti_;};
|
||||
|
||||
/*! Call a member function. This returns a proxy to the function.
|
||||
* The proxy mechanic mechanic is necessary, so the signaute can be passed.
|
||||
@@ -215,7 +216,7 @@ public:
|
||||
template<class Signature>
|
||||
const detail::mem_fn_call_proxy<T, Signature> call(const std::string& name)
|
||||
{
|
||||
return detail::mem_fn_call_proxy<T, Signature>(_data.get(), name, _lib);
|
||||
return detail::mem_fn_call_proxy<T, Signature>(data_.get(), name, lib_);
|
||||
}
|
||||
/*! Call a qualified member function, i.e. const and or volatile.
|
||||
*
|
||||
@@ -228,14 +229,14 @@ public:
|
||||
template<class Tin, class Signature, class = boost::enable_if<detail::unqalified_is_same<T, Tin>>>
|
||||
const detail::mem_fn_call_proxy<Tin, Signature> call(const std::string& name)
|
||||
{
|
||||
return detail::mem_fn_call_proxy<Tin, Signature>(_data.get(), name, _lib);
|
||||
return detail::mem_fn_call_proxy<Tin, Signature>(data_.get(), name, lib_);
|
||||
}
|
||||
///Overload of ->* for an imported method.
|
||||
template<class Tin, class T2>
|
||||
const detail::mem_fn_call_proxy<Tin, boost::dll::experimental::detail::mangled_library_mem_fn<Tin, T2>>
|
||||
operator->*(detail::mangled_library_mem_fn<Tin, T2>& mn)
|
||||
{
|
||||
return detail::mem_fn_call_proxy<Tin, boost::dll::experimental::detail::mangled_library_mem_fn<Tin, T2>>(_data.get(), mn);
|
||||
return detail::mem_fn_call_proxy<Tin, boost::dll::experimental::detail::mangled_library_mem_fn<Tin, T2>>(data_.get(), mn);
|
||||
}
|
||||
|
||||
///Import a method of the class.
|
||||
@@ -243,7 +244,7 @@ public:
|
||||
typename boost::dll::experimental::detail::mangled_import_type<boost::dll::experimental::detail::sequence<T, Args...>>::type
|
||||
import(const std::string & name)
|
||||
{
|
||||
return boost::dll::experimental::import_mangled<T, Args...>(_lib, name);
|
||||
return boost::dll::experimental::import_mangled<T, Args...>(lib_, name);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -259,10 +260,8 @@ inline std::unique_ptr<T, detail::deleter<T>> imported_class<T>::make_data(const
|
||||
|
||||
if (!ctor.has_allocating() || !dtor.has_deleting())
|
||||
{
|
||||
boost::dll::fs::error_code ec;
|
||||
|
||||
ec = boost::dll::fs::make_error_code(
|
||||
boost::dll::fs::errc::bad_file_descriptor
|
||||
std::error_code ec = std::make_error_code(
|
||||
std::errc::bad_file_descriptor
|
||||
);
|
||||
|
||||
// report_error() calls dlsym, do not use it here!
|
||||
@@ -288,10 +287,8 @@ inline std::unique_ptr<T, detail::deleter<T>> imported_class<T>::make_data(const
|
||||
|
||||
if (!ctor.has_standard() || !dtor.has_standard())
|
||||
{
|
||||
boost::dll::fs::error_code ec;
|
||||
|
||||
ec = boost::dll::fs::make_error_code(
|
||||
boost::dll::fs::errc::bad_file_descriptor
|
||||
std::error_code ec = std::make_error_code(
|
||||
std::errc::bad_file_descriptor
|
||||
);
|
||||
|
||||
// report_error() calls dlsym, do not use it here!
|
||||
@@ -316,11 +313,11 @@ inline std::unique_ptr<T, detail::deleter<T>> imported_class<T>::make_data(const
|
||||
template<typename T>
|
||||
template<typename ...Args>
|
||||
imported_class<T>::imported_class(detail::sequence<Args...> *, const smart_library & lib, Args...args)
|
||||
: _lib(lib),
|
||||
_data(make_data<Args...>(lib, static_cast<Args>(args)...)),
|
||||
_is_allocating(false),
|
||||
_size(0),
|
||||
_ti(lib.get_type_info<T>())
|
||||
: lib_(lib),
|
||||
data_(make_data<Args...>(lib_, static_cast<Args>(args)...)),
|
||||
is_allocating_(false),
|
||||
size_(0),
|
||||
ti_(lib.get_type_info<T>())
|
||||
{
|
||||
|
||||
}
|
||||
@@ -328,11 +325,11 @@ imported_class<T>::imported_class(detail::sequence<Args...> *, const smart_libra
|
||||
template<typename T>
|
||||
template<typename ...Args>
|
||||
imported_class<T>::imported_class(detail::sequence<Args...> *, const smart_library & lib, std::size_t size, Args...args)
|
||||
: _lib(lib),
|
||||
_data(make_data<Args...>(lib, size, static_cast<Args>(args)...)),
|
||||
_is_allocating(true),
|
||||
_size(size),
|
||||
_ti(lib.get_type_info<T>())
|
||||
: lib_(lib),
|
||||
data_(make_data<Args...>(lib_, size, static_cast<Args>(args)...)),
|
||||
is_allocating_(true),
|
||||
size_(size),
|
||||
ti_(lib.get_type_info<T>())
|
||||
{
|
||||
|
||||
}
|
||||
@@ -340,11 +337,11 @@ imported_class<T>::imported_class(detail::sequence<Args...> *, const smart_libra
|
||||
template<typename T>
|
||||
template<typename ...Args>
|
||||
imported_class<T>::imported_class(detail::sequence<Args...> *, smart_library && lib, Args...args)
|
||||
: _lib(boost::move(lib)),
|
||||
_data(make_data<Args...>(lib, static_cast<Args>(args)...)),
|
||||
_is_allocating(false),
|
||||
_size(0),
|
||||
_ti(lib.get_type_info<T>())
|
||||
: lib_(std::move(lib)),
|
||||
data_(make_data<Args...>(lib_, static_cast<Args>(args)...)),
|
||||
is_allocating_(false),
|
||||
size_(0),
|
||||
ti_(lib.get_type_info<T>())
|
||||
{
|
||||
|
||||
}
|
||||
@@ -352,11 +349,11 @@ imported_class<T>::imported_class(detail::sequence<Args...> *, smart_library &&
|
||||
template<typename T>
|
||||
template<typename ...Args>
|
||||
imported_class<T>::imported_class(detail::sequence<Args...> *, smart_library && lib, std::size_t size, Args...args)
|
||||
: _lib(boost::move(lib)),
|
||||
_data(make_data<Args...>(lib, size, static_cast<Args>(args)...)),
|
||||
_is_allocating(true),
|
||||
_size(size),
|
||||
_ti(lib.get_type_info<T>())
|
||||
: lib_(std::move(lib)),
|
||||
data_(make_data<Args...>(lib_, size, static_cast<Args>(args)...)),
|
||||
is_allocating_(true),
|
||||
size_(size),
|
||||
ti_(lib.get_type_info<T>())
|
||||
{
|
||||
|
||||
}
|
||||
@@ -364,31 +361,31 @@ imported_class<T>::imported_class(detail::sequence<Args...> *, smart_library &&
|
||||
template<typename T>
|
||||
inline imported_class<T> boost::dll::experimental::imported_class<T>::copy() const
|
||||
{
|
||||
if (this->_is_allocating)
|
||||
return imported_class<T>::template make<const T&>(_lib, *_data);
|
||||
if (this->is_allocating_)
|
||||
return imported_class<T>::template make<const T&>(lib_, *data_);
|
||||
else
|
||||
return imported_class<T>::template make<const T&>(_lib, _size, *_data);
|
||||
return imported_class<T>::template make<const T&>(lib_, size_, *data_);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline imported_class<T> boost::dll::experimental::imported_class<T>::move()
|
||||
{
|
||||
if (this->_is_allocating)
|
||||
return imported_class<T>::template make<T&&>(_lib, *_data);
|
||||
if (this->is_allocating_)
|
||||
return imported_class<T>::template make<T&&>(lib_, *data_);
|
||||
else
|
||||
return imported_class<T>::template make<T&&>(_lib, _size, *_data);
|
||||
return imported_class<T>::template make<T&&>(lib_, size_, *data_);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline void boost::dll::experimental::imported_class<T>::copy_assign(const imported_class<T>& lhs) const
|
||||
{
|
||||
this->call<T&(const T&)>("operator=")(*lhs._data);
|
||||
this->call<T&(const T&)>("operator=")(*lhs.data_);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline void boost::dll::experimental::imported_class<T>::move_assign(imported_class<T>& lhs)
|
||||
{
|
||||
this->call<T&(T&&)>("operator=")(static_cast<T&&>(*lhs._data));
|
||||
this->call<T&(T&&)>("operator=")(static_cast<T&&>(*lhs.data_));
|
||||
}
|
||||
|
||||
|
||||
@@ -423,90 +420,43 @@ inline void boost::dll::experimental::imported_class<T>::move_assign(imported_cl
|
||||
* Overload that accepts path also throws std::bad_alloc in case of insufficient memory.
|
||||
*/
|
||||
template<typename T, typename ... Args> imported_class<T>
|
||||
import_class(const smart_library& lib_, std::size_t size, Args...args)
|
||||
import_class(smart_library lib, std::size_t size, Args...args)
|
||||
{
|
||||
smart_library lib(lib_);
|
||||
|
||||
return imported_class<T>::template make<Args...>(boost::move(lib), size, static_cast<Args>(args)...);
|
||||
return imported_class<T>::template make<Args...>(std::move(lib), size, static_cast<Args>(args)...);
|
||||
}
|
||||
|
||||
//! \overload boost::dll::import_class(const smart_library& lib, std::size_t, Args...)
|
||||
template<typename T, typename ... Args> imported_class<T>
|
||||
import_class(const smart_library& lib_, Args...args)
|
||||
import_class(smart_library lib, Args...args)
|
||||
{
|
||||
smart_library lib(lib_);
|
||||
return imported_class<T>::template make<Args...>(boost::move(lib), static_cast<Args>(args)...);
|
||||
return imported_class<T>::template make<Args...>(std::move(lib), static_cast<Args>(args)...);
|
||||
}
|
||||
|
||||
//! \overload boost::dll::import_class(const smart_library& lib, std::size_t, Args...)
|
||||
template<typename T, typename ... Args> imported_class<T>
|
||||
import_class(const smart_library& lib_, const std::string & alias_name, Args...args)
|
||||
{
|
||||
smart_library lib(lib_);
|
||||
lib.add_type_alias<T>(alias_name);
|
||||
return imported_class<T>::template make<Args...>(boost::move(lib), static_cast<Args>(args)...);
|
||||
}
|
||||
|
||||
//! \overload boost::dll::import_class(const smart_library& lib, std::size_t, Args...)
|
||||
template<typename T, typename ... Args> imported_class<T>
|
||||
import_class(const smart_library& lib_, std::size_t size, const std::string & alias_name, Args...args)
|
||||
{
|
||||
smart_library lib(lib_);
|
||||
|
||||
lib.add_type_alias<T>(alias_name);
|
||||
return imported_class<T>::template make<Args...>(boost::move(lib), size, static_cast<Args>(args)...);
|
||||
}
|
||||
|
||||
//! \overload boost::dll::import_class(const smart_library& lib, std::size_t, Args...)
|
||||
template<typename T, typename ... Args> imported_class<T>
|
||||
import_class(const smart_library& lib_, const std::string & alias_name, std::size_t size, Args...args)
|
||||
{
|
||||
smart_library lib(lib_);
|
||||
|
||||
lib.add_type_alias<T>(alias_name);
|
||||
return imported_class<T>::template make<Args...>(boost::move(lib), size, static_cast<Args>(args)...);
|
||||
}
|
||||
|
||||
//! \overload boost::dll::import_class(const smart_library& lib, std::size_t, Args...)
|
||||
template<typename T, typename ... Args> imported_class<T>
|
||||
import_class(smart_library && lib, Args...args)
|
||||
{
|
||||
return imported_class<T>::template make<Args...>(boost::move(lib), static_cast<Args>(args)...);
|
||||
}
|
||||
|
||||
//! \overload boost::dll::import_class(const smart_library& lib, std::size_t, Args...)
|
||||
template<typename T, typename ... Args> imported_class<T>
|
||||
import_class(smart_library && lib, const std::string & alias_name, Args...args)
|
||||
import_class(smart_library lib, const std::string & alias_name, Args...args)
|
||||
{
|
||||
lib.add_type_alias<T>(alias_name);
|
||||
return imported_class<T>::template make<Args...>(boost::move(lib), static_cast<Args>(args)...);
|
||||
return imported_class<T>::template make<Args...>(std::move(lib), static_cast<Args>(args)...);
|
||||
}
|
||||
|
||||
//! \overload boost::dll::import_class(const smart_library& lib, std::size_t, Args...)
|
||||
template<typename T, typename ... Args> imported_class<T>
|
||||
import_class(smart_library && lib, std::size_t size, Args...args)
|
||||
{
|
||||
return imported_class<T>::template make<Args...>(boost::move(lib), size, static_cast<Args>(args)...);
|
||||
}
|
||||
|
||||
//! \overload boost::dll::import_class(const smart_library& lib, std::size_t, Args...)
|
||||
template<typename T, typename ... Args> imported_class<T>
|
||||
import_class(smart_library && lib, std::size_t size, const std::string & alias_name, Args...args)
|
||||
import_class(smart_library lib, std::size_t size, const std::string & alias_name, Args...args)
|
||||
{
|
||||
lib.add_type_alias<T>(alias_name);
|
||||
return imported_class<T>::template make<Args...>(boost::move(lib), size, static_cast<Args>(args)...);
|
||||
return imported_class<T>::template make<Args...>(std::move(lib), size, static_cast<Args>(args)...);
|
||||
}
|
||||
|
||||
//! \overload boost::dll::import_class(const smart_library& lib, std::size_t, Args...)
|
||||
template<typename T, typename ... Args> imported_class<T>
|
||||
import_class(smart_library && lib, const std::string & alias_name, std::size_t size, Args...args)
|
||||
import_class(smart_library lib, const std::string & alias_name, std::size_t size, Args...args)
|
||||
{
|
||||
lib.add_type_alias<T>(alias_name);
|
||||
return imported_class<T>::template make<Args...>(boost::move(lib), size, static_cast<Args>(args)...);
|
||||
return imported_class<T>::template make<Args...>(std::move(lib), size, static_cast<Args>(args)...);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*! \overload boost::dll::import_class(const smart_library& lib, std::size_t, Args...)
|
||||
* \note This function does add the type alias to the \ref boost::dll::experimental::smart_library.
|
||||
*/
|
||||
|
||||
@@ -19,13 +19,11 @@
|
||||
#endif
|
||||
|
||||
#include <boost/make_shared.hpp>
|
||||
#include <boost/move/move.hpp>
|
||||
#include <boost/dll/smart_library.hpp>
|
||||
#include <boost/dll/detail/import_mangled_helpers.hpp>
|
||||
#include <boost/core/addressof.hpp>
|
||||
#include <boost/core/enable_if.hpp>
|
||||
#include <boost/type_traits/conditional.hpp>
|
||||
#include <boost/type_traits/is_object.hpp>
|
||||
|
||||
#include <memory> // std::addressof
|
||||
#include <type_traits>
|
||||
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
@@ -43,7 +41,7 @@ class mangled_library_function {
|
||||
boost::shared_ptr<shared_library> lib_;
|
||||
function_tuple<Ts...> f_;
|
||||
public:
|
||||
constexpr mangled_library_function(const boost::shared_ptr<shared_library>& lib, Ts*... func_ptr) BOOST_NOEXCEPT
|
||||
constexpr mangled_library_function(const boost::shared_ptr<shared_library>& lib, Ts*... func_ptr) noexcept
|
||||
: lib_(lib)
|
||||
, f_(func_ptr...)
|
||||
{}
|
||||
@@ -77,7 +75,7 @@ class mangled_library_mem_fn<Class, sequence<Ts...>> {
|
||||
call_tuple_t f_;
|
||||
|
||||
public:
|
||||
constexpr mangled_library_mem_fn(const boost::shared_ptr<shared_library>& lib, typename Ts::mem_fn... func_ptr) BOOST_NOEXCEPT
|
||||
constexpr mangled_library_mem_fn(const boost::shared_ptr<shared_library>& lib, typename Ts::mem_fn... func_ptr) noexcept
|
||||
: lib_(lib)
|
||||
, f_(func_ptr...)
|
||||
{}
|
||||
@@ -94,8 +92,8 @@ public:
|
||||
|
||||
|
||||
// simple enough to be here
|
||||
template<class Seq> struct is_variable : boost::false_type {};
|
||||
template<typename T> struct is_variable<sequence<T>> : boost::is_object<T> {};
|
||||
template<class Seq> struct is_variable : std::false_type {};
|
||||
template<typename T> struct is_variable<sequence<T>> : std::is_object<T> {};
|
||||
|
||||
template <class Sequence,
|
||||
bool isFunction = is_function_seq<Sequence>::value,
|
||||
@@ -113,7 +111,7 @@ struct mangled_import_type<sequence<Args...>, true,false,false> //is function
|
||||
{
|
||||
return type(
|
||||
boost::make_shared<shared_library>(p.shared_lib()),
|
||||
boost::addressof(p.get_function<Args>(name))...);
|
||||
std::addressof(p.get_function<Args>(name))...);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -154,7 +152,7 @@ struct mangled_import_type<sequence<T>, false, false, true> //is variable
|
||||
{
|
||||
return type(
|
||||
boost::make_shared<shared_library>(p.shared_lib()),
|
||||
boost::addressof(p.get_variable<T>(name)));
|
||||
std::addressof(p.get_variable<T>(name)));
|
||||
}
|
||||
|
||||
};
|
||||
@@ -186,7 +184,7 @@ struct mangled_import_type<sequence<T>, false, false, true> //is variable
|
||||
* \b Examples:
|
||||
*
|
||||
* \code
|
||||
* boost::function<int(int)> f = import_mangled<int(int)>("test_lib.so", "integer_func_name");
|
||||
* std::function<int(int)> f = import_mangled<int(int)>("test_lib.so", "integer_func_name");
|
||||
*
|
||||
* auto f_cpp11 = import_mangled<int(int)>("test_lib.so", "integer_func_name");
|
||||
* \endcode
|
||||
@@ -264,7 +262,7 @@ BOOST_DLL_MANGLED_IMPORT_RESULT_TYPE import_mangled(const smart_library& lib, co
|
||||
|
||||
//! \overload boost::dll::import(const boost::dll::fs::path& lib, const char* name, load_mode::type mode)
|
||||
template <class ...Args>
|
||||
BOOST_DLL_MANGLED_IMPORT_RESULT_TYPE import_mangled(BOOST_RV_REF(smart_library) lib, const char* name) {
|
||||
BOOST_DLL_MANGLED_IMPORT_RESULT_TYPE import_mangled(smart_library&& lib, const char* name) {
|
||||
typedef typename boost::dll::experimental::detail::mangled_import_type<detail::sequence<Args...>> type;
|
||||
|
||||
return type::make(lib, name);
|
||||
@@ -272,8 +270,8 @@ BOOST_DLL_MANGLED_IMPORT_RESULT_TYPE import_mangled(BOOST_RV_REF(smart_library)
|
||||
|
||||
//! \overload boost::dll::import(const boost::dll::fs::path& lib, const char* name, load_mode::type mode)
|
||||
template <class ...Args>
|
||||
BOOST_DLL_MANGLED_IMPORT_RESULT_TYPE import_mangled(BOOST_RV_REF(smart_library) lib, const std::string& name) {
|
||||
return import_mangled<Args...>(boost::move(lib), name.c_str());
|
||||
BOOST_DLL_MANGLED_IMPORT_RESULT_TYPE import_mangled(smart_library&& lib, const std::string& name) {
|
||||
return import_mangled<Args...>(std::move(lib), name.c_str());
|
||||
}
|
||||
|
||||
//! \overload boost::dll::import(const boost::dll::fs::path& lib, const char* name, load_mode::type mode)
|
||||
@@ -282,7 +280,7 @@ BOOST_DLL_MANGLED_IMPORT_RESULT_TYPE import_mangled(const shared_library& lib, c
|
||||
typedef typename boost::dll::experimental::detail::mangled_import_type<detail::sequence<Args...>> type;
|
||||
|
||||
boost::shared_ptr<boost::dll::experimental::smart_library> p = boost::make_shared<boost::dll::experimental::smart_library>(lib);
|
||||
return type::make(p, name);
|
||||
return type::boostmake(p, name);
|
||||
}
|
||||
|
||||
//! \overload boost::dll::import(const boost::dll::fs::path& lib, const char* name, load_mode::type mode)
|
||||
@@ -293,18 +291,18 @@ BOOST_DLL_MANGLED_IMPORT_RESULT_TYPE import_mangled(const shared_library& lib, c
|
||||
|
||||
//! \overload boost::dll::import(const boost::dll::fs::path& lib, const char* name, load_mode::type mode)
|
||||
template <class ...Args>
|
||||
BOOST_DLL_MANGLED_IMPORT_RESULT_TYPE import_mangled(BOOST_RV_REF(shared_library) lib, const char* name) {
|
||||
BOOST_DLL_MANGLED_IMPORT_RESULT_TYPE import_mangled(shared_library&& lib, const char* name) {
|
||||
typedef typename boost::dll::experimental::detail::mangled_import_type<detail::sequence<Args...>> type;
|
||||
|
||||
boost::dll::experimental::smart_library p(boost::move(lib));
|
||||
boost::dll::experimental::smart_library p(std::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 <class ...Args>
|
||||
BOOST_DLL_MANGLED_IMPORT_RESULT_TYPE import_mangled(BOOST_RV_REF(shared_library) lib, const std::string& name) {
|
||||
return import_mangled<Args...>(boost::move(lib), name.c_str());
|
||||
BOOST_DLL_MANGLED_IMPORT_RESULT_TYPE import_mangled(shared_library&& lib, const std::string& name) {
|
||||
return import_mangled<Args...>(std::move(lib), name.c_str());
|
||||
}
|
||||
|
||||
#undef BOOST_DLL_MANGLED_IMPORT_RESULT_TYPE
|
||||
|
||||
@@ -14,9 +14,9 @@
|
||||
#include <boost/predef/os.h>
|
||||
#include <boost/predef/architecture.h>
|
||||
#include <boost/throw_exception.hpp>
|
||||
#include <boost/type_traits/integral_constant.hpp>
|
||||
|
||||
#include <fstream>
|
||||
#include <type_traits>
|
||||
|
||||
#include <boost/dll/detail/pe_info.hpp>
|
||||
#include <boost/dll/detail/elf_info.hpp>
|
||||
@@ -50,15 +50,15 @@ private:
|
||||
} fmt_;
|
||||
|
||||
/// @cond
|
||||
inline static void throw_if_in_32bit_impl(boost::true_type /* is_32bit_platform */) {
|
||||
inline static void throw_if_in_32bit_impl(std::true_type /* is_32bit_platform */) {
|
||||
boost::throw_exception(std::runtime_error("Not native format: 64bit binary"));
|
||||
}
|
||||
|
||||
inline static void throw_if_in_32bit_impl(boost::false_type /* is_32bit_platform */) BOOST_NOEXCEPT {}
|
||||
inline static void throw_if_in_32bit_impl(std::false_type /* is_32bit_platform */) noexcept {}
|
||||
|
||||
|
||||
inline static void throw_if_in_32bit() {
|
||||
throw_if_in_32bit_impl( boost::integral_constant<bool, (sizeof(void*) == 4)>() );
|
||||
throw_if_in_32bit_impl( std::integral_constant<bool, (sizeof(void*) == 4)>() );
|
||||
}
|
||||
|
||||
static void throw_if_in_windows() {
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#include <boost/predef/os.h>
|
||||
#include <boost/predef/compiler/visualc.h>
|
||||
#include <boost/dll/detail/aggressive_ptr_cast.hpp>
|
||||
|
||||
#if BOOST_OS_WINDOWS
|
||||
# include <boost/winapi/dll.hpp>
|
||||
# include <boost/dll/detail/windows/path_from_handle.hpp>
|
||||
@@ -20,6 +21,8 @@
|
||||
# include <boost/dll/detail/posix/program_location_impl.hpp>
|
||||
#endif
|
||||
|
||||
#include <memory> // std::addressof
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
# pragma once
|
||||
#endif
|
||||
@@ -30,7 +33,7 @@ namespace boost { namespace dll {
|
||||
|
||||
#if BOOST_OS_WINDOWS
|
||||
namespace detail {
|
||||
inline boost::dll::fs::path program_location_impl(boost::dll::fs::error_code& ec) {
|
||||
inline boost::dll::fs::path program_location_impl(std::error_code& ec) {
|
||||
return boost::dll::detail::path_from_handle(NULL, ec);
|
||||
}
|
||||
} // namespace detail
|
||||
@@ -53,12 +56,12 @@ namespace detail {
|
||||
* \endcode
|
||||
*/
|
||||
template <class T>
|
||||
inline boost::dll::fs::path symbol_location_ptr(T ptr_to_symbol, boost::dll::fs::error_code& ec) {
|
||||
static_assert(boost::is_pointer<T>::value, "boost::dll::symbol_location_ptr works only with pointers! `ptr_to_symbol` must be a pointer");
|
||||
inline boost::dll::fs::path symbol_location_ptr(T ptr_to_symbol, std::error_code& ec) {
|
||||
static_assert(std::is_pointer<T>::value, "boost::dll::symbol_location_ptr works only with pointers! `ptr_to_symbol` must be a pointer");
|
||||
boost::dll::fs::path ret;
|
||||
if (!ptr_to_symbol) {
|
||||
ec = boost::dll::fs::make_error_code(
|
||||
boost::dll::fs::errc::bad_address
|
||||
ec = std::make_error_code(
|
||||
std::errc::bad_address
|
||||
);
|
||||
|
||||
return ret;
|
||||
@@ -85,8 +88,8 @@ namespace detail {
|
||||
ret = info.dli_fname;
|
||||
} else {
|
||||
boost::dll::detail::reset_dlerror();
|
||||
ec = boost::dll::fs::make_error_code(
|
||||
boost::dll::fs::errc::bad_address
|
||||
ec = std::make_error_code(
|
||||
std::errc::bad_address
|
||||
);
|
||||
}
|
||||
|
||||
@@ -94,11 +97,11 @@ namespace detail {
|
||||
#endif
|
||||
}
|
||||
|
||||
//! \overload symbol_location_ptr(const void* ptr_to_symbol, boost::dll::fs::error_code& ec)
|
||||
//! \overload symbol_location_ptr(const void* ptr_to_symbol, std::error_code& ec)
|
||||
template <class T>
|
||||
inline boost::dll::fs::path symbol_location_ptr(T ptr_to_symbol) {
|
||||
boost::dll::fs::path ret;
|
||||
boost::dll::fs::error_code ec;
|
||||
std::error_code ec;
|
||||
ret = boost::dll::symbol_location_ptr(ptr_to_symbol, ec);
|
||||
|
||||
if (ec) {
|
||||
@@ -132,10 +135,10 @@ namespace detail {
|
||||
* \endcode
|
||||
*/
|
||||
template <class T>
|
||||
inline boost::dll::fs::path symbol_location(const T& symbol, boost::dll::fs::error_code& ec) {
|
||||
inline boost::dll::fs::path symbol_location(const T& symbol, std::error_code& ec) {
|
||||
ec.clear();
|
||||
return boost::dll::symbol_location_ptr(
|
||||
boost::dll::detail::aggressive_ptr_cast<const void*>(boost::addressof(symbol)),
|
||||
boost::dll::detail::aggressive_ptr_cast<const void*>(std::addressof(symbol)),
|
||||
ec
|
||||
);
|
||||
}
|
||||
@@ -146,15 +149,15 @@ namespace detail {
|
||||
template <class T>
|
||||
inline boost::dll::fs::path symbol_location(const T& symbol, const char* /*workaround*/ = 0)
|
||||
#else
|
||||
//! \overload symbol_location(const T& symbol, boost::dll::fs::error_code& ec)
|
||||
//! \overload symbol_location(const T& symbol, std::error_code& ec)
|
||||
template <class T>
|
||||
inline boost::dll::fs::path symbol_location(const T& symbol)
|
||||
#endif
|
||||
{
|
||||
boost::dll::fs::path ret;
|
||||
boost::dll::fs::error_code ec;
|
||||
std::error_code ec;
|
||||
ret = boost::dll::symbol_location_ptr(
|
||||
boost::dll::detail::aggressive_ptr_cast<const void*>(boost::addressof(symbol)),
|
||||
boost::dll::detail::aggressive_ptr_cast<const void*>(std::addressof(symbol)),
|
||||
ec
|
||||
);
|
||||
|
||||
@@ -180,16 +183,16 @@ namespace detail {
|
||||
* \param ec Variable that will be set to the result of the operation.
|
||||
* \throws std::bad_alloc in case of insufficient memory. Overload that does not accept \forcedlinkfs{error_code} also throws \forcedlinkfs{system_error}.
|
||||
*/
|
||||
static inline boost::dll::fs::path this_line_location(boost::dll::fs::error_code& ec) {
|
||||
typedef boost::dll::fs::path(func_t)(boost::dll::fs::error_code& );
|
||||
static inline boost::dll::fs::path this_line_location(std::error_code& ec) {
|
||||
typedef boost::dll::fs::path(func_t)(std::error_code& );
|
||||
func_t& f = this_line_location;
|
||||
return boost::dll::symbol_location(f, ec);
|
||||
}
|
||||
|
||||
//! \overload this_line_location(boost::dll::fs::error_code& ec)
|
||||
//! \overload this_line_location(std::error_code& ec)
|
||||
static inline boost::dll::fs::path this_line_location() {
|
||||
boost::dll::fs::path ret;
|
||||
boost::dll::fs::error_code ec;
|
||||
std::error_code ec;
|
||||
ret = this_line_location(ec);
|
||||
|
||||
if (ec) {
|
||||
@@ -213,15 +216,15 @@ namespace detail {
|
||||
* \param ec Variable that will be set to the result of the operation.
|
||||
* \throws std::bad_alloc in case of insufficient memory. Overload that does not accept \forcedlinkfs{error_code} also throws \forcedlinkfs{system_error}.
|
||||
*/
|
||||
inline boost::dll::fs::path program_location(boost::dll::fs::error_code& ec) {
|
||||
inline boost::dll::fs::path program_location(std::error_code& ec) {
|
||||
ec.clear();
|
||||
return boost::dll::detail::program_location_impl(ec);
|
||||
}
|
||||
|
||||
//! \overload program_location(boost::dll::fs::error_code& ec) {
|
||||
//! \overload program_location(std::error_code& ec) {
|
||||
inline boost::dll::fs::path program_location() {
|
||||
boost::dll::fs::path ret;
|
||||
boost::dll::fs::error_code ec;
|
||||
std::error_code ec;
|
||||
ret = boost::dll::detail::program_location_impl(ec);
|
||||
|
||||
if (ec) {
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
#include <boost/predef/os.h>
|
||||
#include <boost/core/enable_if.hpp>
|
||||
#include <boost/core/explicit_operator_bool.hpp>
|
||||
#include <boost/type_traits/is_member_pointer.hpp>
|
||||
#include <boost/dll/detail/system_error.hpp>
|
||||
#include <boost/dll/detail/aggressive_ptr_cast.hpp>
|
||||
|
||||
@@ -26,6 +25,9 @@
|
||||
# include <boost/dll/detail/posix/shared_library_impl.hpp>
|
||||
#endif
|
||||
|
||||
#include <type_traits>
|
||||
#include <utility> // std::move
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
# pragma once
|
||||
#endif
|
||||
@@ -50,7 +52,6 @@ class shared_library
|
||||
/// @endcond
|
||||
{
|
||||
typedef boost::dll::detail::shared_library_impl base_t;
|
||||
BOOST_COPYABLE_AND_MOVABLE(shared_library)
|
||||
|
||||
public:
|
||||
#ifdef BOOST_DLL_DOXYGEN
|
||||
@@ -65,7 +66,7 @@ public:
|
||||
* \post this->is_loaded() returns false.
|
||||
* \throw Nothing.
|
||||
*/
|
||||
shared_library() BOOST_NOEXCEPT {}
|
||||
shared_library() noexcept = default;
|
||||
|
||||
/*!
|
||||
* Copy constructor that increments the reference count of an underlying shared library.
|
||||
@@ -90,7 +91,7 @@ public:
|
||||
* \post lib == *this
|
||||
* \throw std::bad_alloc in case of insufficient memory.
|
||||
*/
|
||||
shared_library(const shared_library& lib, boost::dll::fs::error_code& ec)
|
||||
shared_library(const shared_library& lib, std::error_code& ec)
|
||||
: base_t()
|
||||
{
|
||||
assign(lib, ec);
|
||||
@@ -103,8 +104,8 @@ public:
|
||||
* \post lib.is_loaded() returns false, this->is_loaded() return true.
|
||||
* \throw Nothing.
|
||||
*/
|
||||
shared_library(BOOST_RV_REF(shared_library) lib) BOOST_NOEXCEPT
|
||||
: base_t(boost::move(static_cast<base_t&>(lib)))
|
||||
shared_library(shared_library&& lib) noexcept
|
||||
: base_t(std::move(lib))
|
||||
{}
|
||||
|
||||
/*!
|
||||
@@ -128,12 +129,12 @@ public:
|
||||
* \param ec Variable that will be set to the result of the operation.
|
||||
* \throw std::bad_alloc in case of insufficient memory.
|
||||
*/
|
||||
shared_library(const boost::dll::fs::path& lib_path, boost::dll::fs::error_code& ec, load_mode::type mode = load_mode::default_mode) {
|
||||
shared_library(const boost::dll::fs::path& lib_path, std::error_code& ec, load_mode::type mode = load_mode::default_mode) {
|
||||
shared_library::load(lib_path, mode, ec);
|
||||
}
|
||||
|
||||
//! \overload shared_library(const boost::dll::fs::path& lib_path, boost::dll::fs::error_code& ec, load_mode::type mode = load_mode::default_mode)
|
||||
shared_library(const boost::dll::fs::path& lib_path, load_mode::type mode, boost::dll::fs::error_code& ec) {
|
||||
//! \overload shared_library(const boost::dll::fs::path& lib_path, std::error_code& ec, load_mode::type mode = load_mode::default_mode)
|
||||
shared_library(const boost::dll::fs::path& lib_path, load_mode::type mode, std::error_code& ec) {
|
||||
shared_library::load(lib_path, mode, ec);
|
||||
}
|
||||
|
||||
@@ -142,7 +143,7 @@ public:
|
||||
*
|
||||
* \param handle The native handle.
|
||||
*/
|
||||
explicit shared_library(native_handle_t handle)
|
||||
explicit shared_library(native_handle_t handle) noexcept
|
||||
: base_t(handle)
|
||||
{}
|
||||
|
||||
@@ -153,8 +154,8 @@ public:
|
||||
* \post lib == *this
|
||||
* \throw \forcedlinkfs{system_error}, std::bad_alloc in case of insufficient memory.
|
||||
*/
|
||||
shared_library& operator=(BOOST_COPY_ASSIGN_REF(shared_library) lib) {
|
||||
boost::dll::fs::error_code ec;
|
||||
shared_library& operator=(const shared_library& lib) {
|
||||
std::error_code ec;
|
||||
assign(lib, ec);
|
||||
if (ec) {
|
||||
boost::dll::detail::report_error(ec, "boost::dll::shared_library::operator= failed");
|
||||
@@ -170,7 +171,7 @@ public:
|
||||
* \post lib.is_loaded() returns false.
|
||||
* \throw Nothing.
|
||||
*/
|
||||
shared_library& operator=(BOOST_RV_REF(shared_library) lib) BOOST_NOEXCEPT {
|
||||
shared_library& operator=(shared_library&& lib) noexcept {
|
||||
if (lib.native() != native()) {
|
||||
swap(lib);
|
||||
}
|
||||
@@ -185,7 +186,7 @@ public:
|
||||
*
|
||||
* \throw Nothing.
|
||||
*/
|
||||
~shared_library() BOOST_NOEXCEPT {}
|
||||
~shared_library() = default;
|
||||
|
||||
/*!
|
||||
* Makes *this share the same shared object as lib. If *this is loaded, then unloads it.
|
||||
@@ -195,7 +196,7 @@ public:
|
||||
* \param ec Variable that will be set to the result of the operation.
|
||||
* \throw std::bad_alloc in case of insufficient memory.
|
||||
*/
|
||||
shared_library& assign(const shared_library& lib, boost::dll::fs::error_code& ec) {
|
||||
shared_library& assign(const shared_library& lib, std::error_code& ec) {
|
||||
ec.clear();
|
||||
|
||||
if (native() == lib.native()) {
|
||||
@@ -229,7 +230,7 @@ public:
|
||||
* \throw \forcedlinkfs{system_error}, std::bad_alloc in case of insufficient memory.
|
||||
*/
|
||||
shared_library& assign(const shared_library& lib) {
|
||||
boost::dll::fs::error_code ec;
|
||||
std::error_code ec;
|
||||
assign(lib, ec);
|
||||
if (ec) {
|
||||
boost::dll::detail::report_error(ec, "boost::dll::shared_library::assign() failed");
|
||||
@@ -251,7 +252,7 @@ public:
|
||||
*
|
||||
*/
|
||||
void load(const boost::dll::fs::path& lib_path, load_mode::type mode = load_mode::default_mode) {
|
||||
boost::dll::fs::error_code ec;
|
||||
std::error_code ec;
|
||||
|
||||
base_t::load(lib_path, mode, ec);
|
||||
|
||||
@@ -272,13 +273,13 @@ public:
|
||||
* \param mode A mode that will be used on library load.
|
||||
* \throw std::bad_alloc in case of insufficient memory.
|
||||
*/
|
||||
void load(const boost::dll::fs::path& lib_path, boost::dll::fs::error_code& ec, load_mode::type mode = load_mode::default_mode) {
|
||||
void load(const boost::dll::fs::path& lib_path, std::error_code& ec, load_mode::type mode = load_mode::default_mode) {
|
||||
ec.clear();
|
||||
base_t::load(lib_path, mode, ec);
|
||||
}
|
||||
|
||||
//! \overload void load(const boost::dll::fs::path& lib_path, boost::dll::fs::error_code& ec, load_mode::type mode = load_mode::default_mode)
|
||||
void load(const boost::dll::fs::path& lib_path, load_mode::type mode, boost::dll::fs::error_code& ec) {
|
||||
//! \overload void load(const boost::dll::fs::path& lib_path, std::error_code& ec, load_mode::type mode = load_mode::default_mode)
|
||||
void load(const boost::dll::fs::path& lib_path, load_mode::type mode, std::error_code& ec) {
|
||||
ec.clear();
|
||||
base_t::load(lib_path, mode, ec);
|
||||
}
|
||||
@@ -291,7 +292,7 @@ public:
|
||||
* \post this->is_loaded() returns false.
|
||||
* \throw Nothing.
|
||||
*/
|
||||
void unload() BOOST_NOEXCEPT {
|
||||
void unload() noexcept {
|
||||
base_t::unload();
|
||||
}
|
||||
|
||||
@@ -301,27 +302,19 @@ public:
|
||||
* \return true if a library has been loaded.
|
||||
* \throw Nothing.
|
||||
*/
|
||||
bool is_loaded() const BOOST_NOEXCEPT {
|
||||
bool is_loaded() const noexcept {
|
||||
return base_t::is_loaded();
|
||||
}
|
||||
|
||||
/*!
|
||||
* Check if an library is not loaded.
|
||||
*
|
||||
* \return true if a library has not been loaded.
|
||||
* \throw Nothing.
|
||||
*/
|
||||
bool operator!() const BOOST_NOEXCEPT {
|
||||
return !is_loaded();
|
||||
}
|
||||
|
||||
/*!
|
||||
* Check if an library is loaded.
|
||||
*
|
||||
* \return true if a library has been loaded.
|
||||
* \throw Nothing.
|
||||
*/
|
||||
BOOST_EXPLICIT_OPERATOR_BOOL()
|
||||
explicit operator bool() const noexcept {
|
||||
return is_loaded();
|
||||
}
|
||||
|
||||
/*!
|
||||
* Search for a given symbol on loaded library. Works for all symbols, including alias names.
|
||||
@@ -330,13 +323,13 @@ public:
|
||||
* \return `true` if the loaded library contains a symbol with a given name.
|
||||
* \throw Nothing.
|
||||
*/
|
||||
bool has(const char* symbol_name) const BOOST_NOEXCEPT {
|
||||
boost::dll::fs::error_code ec;
|
||||
bool has(const char* symbol_name) const noexcept {
|
||||
std::error_code ec;
|
||||
return is_loaded() && !!base_t::symbol_addr(symbol_name, ec) && !ec;
|
||||
}
|
||||
|
||||
//! \overload bool has(const char* symbol_name) const
|
||||
bool has(const std::string& symbol_name) const BOOST_NOEXCEPT {
|
||||
bool has(const std::string& symbol_name) const noexcept {
|
||||
return has(symbol_name.c_str());
|
||||
}
|
||||
|
||||
@@ -357,19 +350,19 @@ public:
|
||||
* \throw \forcedlinkfs{system_error} if symbol does not exist or if the DLL/DSO was not loaded.
|
||||
*/
|
||||
template <typename T>
|
||||
inline typename boost::enable_if_c<boost::is_member_pointer<T>::value || boost::is_reference<T>::value, T>::type get(const std::string& symbol_name) const {
|
||||
inline typename std::enable_if<std::is_member_pointer<T>::value || std::is_reference<T>::value, T>::type get(const std::string& symbol_name) const {
|
||||
return get<T>(symbol_name.c_str());
|
||||
}
|
||||
|
||||
//! \overload T& get(const std::string& symbol_name) const
|
||||
template <typename T>
|
||||
inline typename boost::disable_if_c<boost::is_member_pointer<T>::value || boost::is_reference<T>::value, T&>::type get(const std::string& symbol_name) const {
|
||||
inline typename std::enable_if<!(std::is_member_pointer<T>::value || std::is_reference<T>::value), T&>::type get(const std::string& symbol_name) const {
|
||||
return get<T>(symbol_name.c_str());
|
||||
}
|
||||
|
||||
//! \overload T& get(const std::string& symbol_name) const
|
||||
template <typename T>
|
||||
inline typename boost::enable_if_c<boost::is_member_pointer<T>::value || boost::is_reference<T>::value, T>::type get(const char* symbol_name) const {
|
||||
inline typename std::enable_if<std::is_member_pointer<T>::value || std::is_reference<T>::value, T>::type get(const char* symbol_name) const {
|
||||
return boost::dll::detail::aggressive_ptr_cast<T>(
|
||||
get_void(symbol_name)
|
||||
);
|
||||
@@ -377,7 +370,7 @@ public:
|
||||
|
||||
//! \overload T& get(const std::string& symbol_name) const
|
||||
template <typename T>
|
||||
inline typename boost::disable_if_c<boost::is_member_pointer<T>::value || boost::is_reference<T>::value, T&>::type get(const char* symbol_name) const {
|
||||
inline typename std::enable_if<!(std::is_member_pointer<T>::value || std::is_reference<T>::value), T&>::type get(const char* symbol_name) const {
|
||||
return *boost::dll::detail::aggressive_ptr_cast<T*>(
|
||||
get_void(symbol_name)
|
||||
);
|
||||
@@ -411,11 +404,11 @@ private:
|
||||
// get_void is required to reduce binary size: it does not depend on a template
|
||||
// parameter and will be instantiated only once.
|
||||
void* get_void(const char* sb) const {
|
||||
boost::dll::fs::error_code ec;
|
||||
std::error_code ec;
|
||||
|
||||
if (!is_loaded()) {
|
||||
ec = boost::dll::fs::make_error_code(
|
||||
boost::dll::fs::errc::bad_file_descriptor
|
||||
ec = std::make_error_code(
|
||||
std::errc::bad_file_descriptor
|
||||
);
|
||||
|
||||
// report_error() calls dlsym, do not use it here!
|
||||
@@ -442,7 +435,7 @@ public:
|
||||
*
|
||||
* \return Platform-specific handle.
|
||||
*/
|
||||
native_handle_t native() const BOOST_NOEXCEPT {
|
||||
native_handle_t native() const noexcept {
|
||||
return base_t::native();
|
||||
}
|
||||
|
||||
@@ -459,10 +452,10 @@ public:
|
||||
* \throw \forcedlinkfs{system_error}, std::bad_alloc.
|
||||
*/
|
||||
boost::dll::fs::path location() const {
|
||||
boost::dll::fs::error_code ec;
|
||||
std::error_code ec;
|
||||
if (!is_loaded()) {
|
||||
ec = boost::dll::fs::make_error_code(
|
||||
boost::dll::fs::errc::bad_file_descriptor
|
||||
ec = std::make_error_code(
|
||||
std::errc::bad_file_descriptor
|
||||
);
|
||||
|
||||
boost::throw_exception(
|
||||
@@ -494,10 +487,10 @@ public:
|
||||
* \return Full path to the shared library.
|
||||
* \throw std::bad_alloc.
|
||||
*/
|
||||
boost::dll::fs::path location(boost::dll::fs::error_code& ec) const {
|
||||
boost::dll::fs::path location(std::error_code& ec) const {
|
||||
if (!is_loaded()) {
|
||||
ec = boost::dll::fs::make_error_code(
|
||||
boost::dll::fs::errc::bad_file_descriptor
|
||||
ec = std::make_error_code(
|
||||
std::errc::bad_file_descriptor
|
||||
);
|
||||
|
||||
return boost::dll::fs::path();
|
||||
@@ -546,7 +539,7 @@ public:
|
||||
* \param rhs Library to swap with.
|
||||
* \throw Nothing.
|
||||
*/
|
||||
void swap(shared_library& rhs) BOOST_NOEXCEPT {
|
||||
void swap(shared_library& rhs) noexcept {
|
||||
base_t::swap(rhs);
|
||||
}
|
||||
};
|
||||
@@ -554,22 +547,22 @@ public:
|
||||
|
||||
|
||||
/// Very fast equality check that compares the actual DLL/DSO objects. Throws nothing.
|
||||
inline bool operator==(const shared_library& lhs, const shared_library& rhs) BOOST_NOEXCEPT {
|
||||
inline bool operator==(const shared_library& lhs, const shared_library& rhs) noexcept {
|
||||
return lhs.native() == rhs.native();
|
||||
}
|
||||
|
||||
/// Very fast inequality check that compares the actual DLL/DSO objects. Throws nothing.
|
||||
inline bool operator!=(const shared_library& lhs, const shared_library& rhs) BOOST_NOEXCEPT {
|
||||
inline bool operator!=(const shared_library& lhs, const shared_library& rhs) noexcept {
|
||||
return lhs.native() != rhs.native();
|
||||
}
|
||||
|
||||
/// Compare the actual DLL/DSO objects without any guarantee to be stable between runs. Throws nothing.
|
||||
inline bool operator<(const shared_library& lhs, const shared_library& rhs) BOOST_NOEXCEPT {
|
||||
inline bool operator<(const shared_library& lhs, const shared_library& rhs) noexcept {
|
||||
return lhs.native() < rhs.native();
|
||||
}
|
||||
|
||||
/// Swaps two shared libraries. Does not invalidate symbols and functions loaded from libraries. Throws nothing.
|
||||
inline void swap(shared_library& lhs, shared_library& rhs) BOOST_NOEXCEPT {
|
||||
inline void swap(shared_library& lhs, shared_library& rhs) noexcept {
|
||||
lhs.swap(rhs);
|
||||
}
|
||||
|
||||
|
||||
@@ -207,37 +207,37 @@ enum type {
|
||||
|
||||
|
||||
/// Free operators for load_mode::type flag manipulation.
|
||||
BOOST_CONSTEXPR inline type operator|(type left, type right) BOOST_NOEXCEPT {
|
||||
BOOST_CONSTEXPR inline type operator|(type left, type right) noexcept {
|
||||
return static_cast<type>(
|
||||
static_cast<unsigned int>(left) | static_cast<unsigned int>(right)
|
||||
);
|
||||
}
|
||||
BOOST_CXX14_CONSTEXPR inline type& operator|=(type& left, type right) BOOST_NOEXCEPT {
|
||||
BOOST_CXX14_CONSTEXPR inline type& operator|=(type& left, type right) noexcept {
|
||||
left = left | right;
|
||||
return left;
|
||||
}
|
||||
|
||||
BOOST_CONSTEXPR inline type operator&(type left, type right) BOOST_NOEXCEPT {
|
||||
BOOST_CONSTEXPR inline type operator&(type left, type right) noexcept {
|
||||
return static_cast<type>(
|
||||
static_cast<unsigned int>(left) & static_cast<unsigned int>(right)
|
||||
);
|
||||
}
|
||||
BOOST_CXX14_CONSTEXPR inline type& operator&=(type& left, type right) BOOST_NOEXCEPT {
|
||||
BOOST_CXX14_CONSTEXPR inline type& operator&=(type& left, type right) noexcept {
|
||||
left = left & right;
|
||||
return left;
|
||||
}
|
||||
|
||||
BOOST_CONSTEXPR inline type operator^(type left, type right) BOOST_NOEXCEPT {
|
||||
BOOST_CONSTEXPR inline type operator^(type left, type right) noexcept {
|
||||
return static_cast<type>(
|
||||
static_cast<unsigned int>(left) ^ static_cast<unsigned int>(right)
|
||||
);
|
||||
}
|
||||
BOOST_CXX14_CONSTEXPR inline type& operator^=(type& left, type right) BOOST_NOEXCEPT {
|
||||
BOOST_CXX14_CONSTEXPR inline type& operator^=(type& left, type right) noexcept {
|
||||
left = left ^ right;
|
||||
return left;
|
||||
}
|
||||
|
||||
BOOST_CONSTEXPR inline type operator~(type left) BOOST_NOEXCEPT {
|
||||
BOOST_CONSTEXPR inline type operator~(type left) noexcept {
|
||||
return static_cast<type>(
|
||||
~static_cast<unsigned int>(left)
|
||||
);
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
#define BOOST_DLL_SMART_LIBRARY_HPP_
|
||||
|
||||
/// \file boost/dll/smart_library.hpp
|
||||
/// \warning Extremely experimental! Requires C++11! Will change in next version of Boost! boost/dll/smart_library.hpp is not included in boost/dll.hpp
|
||||
/// \warning Extremely experimental! May change in next version of Boost! boost/dll/smart_library.hpp is not included in boost/dll.hpp
|
||||
/// \brief Contains the boost::dll::experimental::smart_library class for loading mangled symbols.
|
||||
|
||||
#include <boost/dll/config.hpp>
|
||||
@@ -27,11 +27,9 @@
|
||||
#include <boost/dll/detail/get_mem_fn_type.hpp>
|
||||
#include <boost/dll/detail/ctor_dtor.hpp>
|
||||
#include <boost/dll/detail/type_info.hpp>
|
||||
#include <boost/type_traits/is_object.hpp>
|
||||
#include <boost/type_traits/is_void.hpp>
|
||||
#include <boost/type_traits/is_function.hpp>
|
||||
|
||||
|
||||
#include <type_traits>
|
||||
#include <utility> // std::move
|
||||
|
||||
namespace boost {
|
||||
namespace dll {
|
||||
@@ -53,10 +51,10 @@ using boost::dll::detail::destructor;
|
||||
* Member functions must be defined outside of the class to be exported. That is:
|
||||
* \code
|
||||
* //not exported:
|
||||
* struct BOOST_SYMBOL_EXPORT my_class { void func() {}};
|
||||
* struct BOOST_SYMBOL_EXPORT my_class { void func() {} };
|
||||
* //exported
|
||||
* struct BOOST_SYMBOL_EXPORT my_class { void func();};
|
||||
* void my_class::func() {};
|
||||
* struct BOOST_SYMBOL_EXPORT my_class { void func(); };
|
||||
* void my_class::func() {}
|
||||
* \endcode
|
||||
*
|
||||
* With the current analysis, the first version does get exported in MSVC.
|
||||
@@ -72,14 +70,14 @@ using boost::dll::detail::destructor;
|
||||
* This does however not happen when the value is set inside the constructor function.
|
||||
*/
|
||||
class smart_library {
|
||||
shared_library _lib;
|
||||
detail::mangled_storage_impl _storage;
|
||||
shared_library lib_;
|
||||
detail::mangled_storage_impl storage_;
|
||||
|
||||
public:
|
||||
/*!
|
||||
* Get the underlying shared_library
|
||||
*/
|
||||
const shared_library &shared_lib() const {return _lib;}
|
||||
const shared_library &shared_lib() const noexcept { return lib_;}
|
||||
|
||||
using mangled_storage = detail::mangled_storage_impl;
|
||||
/*!
|
||||
@@ -87,18 +85,18 @@ public:
|
||||
*
|
||||
* \throw Nothing.
|
||||
*/
|
||||
const mangled_storage &symbol_storage() const {return _storage;}
|
||||
const mangled_storage &symbol_storage() const noexcept { return storage_; }
|
||||
|
||||
///Overload, for current development.
|
||||
mangled_storage &symbol_storage() {return _storage;}
|
||||
mangled_storage &symbol_storage() noexcept { return storage_; }
|
||||
|
||||
//! \copydoc shared_library::shared_library()
|
||||
smart_library() BOOST_NOEXCEPT {};
|
||||
smart_library() = default;
|
||||
|
||||
//! \copydoc shared_library::shared_library(const boost::dll::fs::path& lib_path, load_mode::type mode = load_mode::default_mode)
|
||||
smart_library(const boost::dll::fs::path& lib_path, load_mode::type mode = load_mode::default_mode) {
|
||||
_lib.load(lib_path, mode);
|
||||
_storage.load(lib_path);
|
||||
lib_.load(lib_path, mode);
|
||||
storage_.load(lib_path);
|
||||
}
|
||||
|
||||
//! \copydoc shared_library::shared_library(const boost::dll::fs::path& lib_path, boost::dll::fs::error_code& ec, load_mode::type mode = load_mode::default_mode)
|
||||
@@ -117,9 +115,7 @@ public:
|
||||
*
|
||||
* \throw Nothing.
|
||||
*/
|
||||
smart_library(const smart_library & lib) BOOST_NOEXCEPT
|
||||
: _lib(lib._lib), _storage(lib._storage)
|
||||
{}
|
||||
smart_library(const smart_library & lib) = default;
|
||||
/*!
|
||||
* Move a smart_library object.
|
||||
*
|
||||
@@ -127,9 +123,7 @@ public:
|
||||
*
|
||||
* \throw Nothing.
|
||||
*/
|
||||
smart_library(BOOST_RV_REF(smart_library) lib) BOOST_NOEXCEPT
|
||||
: _lib(boost::move(lib._lib)), _storage(boost::move(lib._storage))
|
||||
{}
|
||||
smart_library(smart_library&& lib) = default;
|
||||
|
||||
/*!
|
||||
* Construct from a shared_library object.
|
||||
@@ -138,10 +132,10 @@ public:
|
||||
*
|
||||
* \throw Nothing.
|
||||
*/
|
||||
explicit smart_library(const shared_library & lib) BOOST_NOEXCEPT
|
||||
: _lib(lib)
|
||||
explicit smart_library(const shared_library & lib) noexcept
|
||||
: lib_(lib)
|
||||
{
|
||||
_storage.load(lib.location());
|
||||
storage_.load(lib.location());
|
||||
}
|
||||
/*!
|
||||
* Construct from a shared_library object.
|
||||
@@ -150,10 +144,10 @@ public:
|
||||
*
|
||||
* \throw Nothing.
|
||||
*/
|
||||
explicit smart_library(BOOST_RV_REF(shared_library) lib) BOOST_NOEXCEPT
|
||||
: _lib(boost::move(static_cast<shared_library&>(lib)))
|
||||
explicit smart_library(shared_library&& lib) noexcept
|
||||
: lib_(std::move(lib))
|
||||
{
|
||||
_storage.load(lib.location());
|
||||
storage_.load(lib.location());
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -164,13 +158,13 @@ public:
|
||||
*
|
||||
* \throw Nothing.
|
||||
*/
|
||||
~smart_library() BOOST_NOEXCEPT {};
|
||||
~smart_library() = default;
|
||||
|
||||
//! \copydoc shared_library::load(const boost::dll::fs::path& lib_path, load_mode::type mode = load_mode::default_mode)
|
||||
void load(const boost::dll::fs::path& lib_path, load_mode::type mode = load_mode::default_mode) {
|
||||
boost::dll::fs::error_code ec;
|
||||
_storage.load(lib_path);
|
||||
_lib.load(lib_path, mode, ec);
|
||||
storage_.load(lib_path);
|
||||
lib_.load(lib_path, mode, ec);
|
||||
|
||||
if (ec) {
|
||||
boost::dll::detail::report_error(ec, "load() failed");
|
||||
@@ -180,15 +174,15 @@ public:
|
||||
//! \copydoc shared_library::load(const boost::dll::fs::path& lib_path, boost::dll::fs::error_code& ec, load_mode::type mode = load_mode::default_mode)
|
||||
void load(const boost::dll::fs::path& lib_path, boost::dll::fs::error_code& ec, load_mode::type mode = load_mode::default_mode) {
|
||||
ec.clear();
|
||||
_storage.load(lib_path);
|
||||
_lib.load(lib_path, mode, ec);
|
||||
storage_.load(lib_path);
|
||||
lib_.load(lib_path, mode, ec);
|
||||
}
|
||||
|
||||
//! \copydoc shared_library::load(const boost::dll::fs::path& lib_path, load_mode::type mode, boost::dll::fs::error_code& ec)
|
||||
void load(const boost::dll::fs::path& lib_path, load_mode::type mode, boost::dll::fs::error_code& ec) {
|
||||
ec.clear();
|
||||
_storage.load(lib_path);
|
||||
_lib.load(lib_path, mode, ec);
|
||||
storage_.load(lib_path);
|
||||
lib_.load(lib_path, mode, ec);
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -206,7 +200,7 @@ public:
|
||||
*/
|
||||
template<typename T>
|
||||
T& get_variable(const std::string &name) const {
|
||||
return _lib.get<T>(_storage.get_variable<T>(name));
|
||||
return lib_.get<T>(storage_.get_variable<T>(name));
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -232,7 +226,7 @@ public:
|
||||
*/
|
||||
template<typename Func>
|
||||
Func& get_function(const std::string &name) const {
|
||||
return _lib.get<Func>(_storage.get_function<Func>(name));
|
||||
return lib_.get<Func>(storage_.get_function<Func>(name));
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -261,8 +255,8 @@ public:
|
||||
*/
|
||||
template<typename Class, typename Func>
|
||||
typename boost::dll::detail::get_mem_fn_type<Class, Func>::mem_fn get_mem_fn(const std::string& name) const {
|
||||
return _lib.get<typename boost::dll::detail::get_mem_fn_type<Class, Func>::mem_fn>(
|
||||
_storage.get_mem_fn<Class, Func>(name)
|
||||
return lib_.get<typename boost::dll::detail::get_mem_fn_type<Class, Func>::mem_fn>(
|
||||
storage_.get_mem_fn<Class, Func>(name)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -284,7 +278,7 @@ public:
|
||||
*/
|
||||
template<typename Signature>
|
||||
constructor<Signature> get_constructor() const {
|
||||
return boost::dll::detail::load_ctor<Signature>(_lib, _storage.get_constructor<Signature>());
|
||||
return boost::dll::detail::load_ctor<Signature>(lib_, storage_.get_constructor<Signature>());
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -306,7 +300,7 @@ public:
|
||||
*/
|
||||
template<typename Class>
|
||||
destructor<Class> get_destructor() const {
|
||||
return boost::dll::detail::load_dtor<Class>(_lib, _storage.get_destructor<Class>());
|
||||
return boost::dll::detail::load_dtor<Class>(lib_, storage_.get_destructor<Class>());
|
||||
}
|
||||
/*!
|
||||
* Load the typeinfo of the given type.
|
||||
@@ -328,7 +322,7 @@ public:
|
||||
template<typename Class>
|
||||
const std::type_info& get_type_info() const
|
||||
{
|
||||
return boost::dll::detail::load_type_info<Class>(_lib, _storage);
|
||||
return boost::dll::detail::load_type_info<Class>(lib_, storage_);
|
||||
}
|
||||
/**
|
||||
* This function can be used to add a type alias.
|
||||
@@ -352,69 +346,66 @@ public:
|
||||
* \warning The alias will only be applied for the type signature, it will not replace the token in the scoped name.
|
||||
*/
|
||||
template<typename Alias> void add_type_alias(const std::string& name) {
|
||||
this->_storage.add_alias<Alias>(name);
|
||||
this->storage_.add_alias<Alias>(name);
|
||||
}
|
||||
|
||||
//! \copydoc shared_library::unload()
|
||||
void unload() BOOST_NOEXCEPT {
|
||||
_storage.clear();
|
||||
_lib.unload();
|
||||
void unload() noexcept {
|
||||
storage_.clear();
|
||||
lib_.unload();
|
||||
}
|
||||
|
||||
//! \copydoc shared_library::is_loaded() const
|
||||
bool is_loaded() const BOOST_NOEXCEPT {
|
||||
return _lib.is_loaded();
|
||||
}
|
||||
|
||||
//! \copydoc shared_library::operator!() const
|
||||
bool operator!() const BOOST_NOEXCEPT {
|
||||
return !is_loaded();
|
||||
bool is_loaded() const noexcept {
|
||||
return lib_.is_loaded();
|
||||
}
|
||||
|
||||
//! \copydoc shared_library::operator bool() const
|
||||
BOOST_EXPLICIT_OPERATOR_BOOL()
|
||||
explicit operator bool() const noexcept {
|
||||
return is_loaded();
|
||||
}
|
||||
|
||||
//! \copydoc shared_library::has(const char* symbol_name) const
|
||||
bool has(const char* symbol_name) const BOOST_NOEXCEPT {
|
||||
return _lib.has(symbol_name);
|
||||
bool has(const char* symbol_name) const noexcept {
|
||||
return lib_.has(symbol_name);
|
||||
}
|
||||
|
||||
//! \copydoc shared_library::has(const std::string& symbol_name) const
|
||||
bool has(const std::string& symbol_name) const BOOST_NOEXCEPT {
|
||||
return _lib.has(symbol_name);
|
||||
bool has(const std::string& symbol_name) const noexcept {
|
||||
return lib_.has(symbol_name);
|
||||
}
|
||||
|
||||
//! \copydoc shared_library::assign(const shared_library& lib)
|
||||
smart_library& assign(const smart_library& lib) {
|
||||
_lib.assign(lib._lib);
|
||||
_storage.assign(lib._storage);
|
||||
lib_.assign(lib.lib_);
|
||||
storage_.assign(lib.storage_);
|
||||
return *this;
|
||||
}
|
||||
|
||||
//! \copydoc shared_library::swap(shared_library& rhs)
|
||||
void swap(smart_library& rhs) BOOST_NOEXCEPT {
|
||||
_lib.swap(rhs._lib);
|
||||
_storage.swap(rhs._storage);
|
||||
void swap(smart_library& rhs) noexcept {
|
||||
lib_.swap(rhs.lib_);
|
||||
storage_.swap(rhs.storage_);
|
||||
}
|
||||
};
|
||||
|
||||
/// Very fast equality check that compares the actual DLL/DSO objects. Throws nothing.
|
||||
inline bool operator==(const smart_library& lhs, const smart_library& rhs) BOOST_NOEXCEPT {
|
||||
inline bool operator==(const smart_library& lhs, const smart_library& rhs) noexcept {
|
||||
return lhs.shared_lib().native() == rhs.shared_lib().native();
|
||||
}
|
||||
|
||||
/// Very fast inequality check that compares the actual DLL/DSO objects. Throws nothing.
|
||||
inline bool operator!=(const smart_library& lhs, const smart_library& rhs) BOOST_NOEXCEPT {
|
||||
inline bool operator!=(const smart_library& lhs, const smart_library& rhs) noexcept {
|
||||
return lhs.shared_lib().native() != rhs.shared_lib().native();
|
||||
}
|
||||
|
||||
/// Compare the actual DLL/DSO objects without any guarantee to be stable between runs. Throws nothing.
|
||||
inline bool operator<(const smart_library& lhs, const smart_library& rhs) BOOST_NOEXCEPT {
|
||||
inline bool operator<(const smart_library& lhs, const smart_library& rhs) noexcept {
|
||||
return lhs.shared_lib().native() < rhs.shared_lib().native();
|
||||
}
|
||||
|
||||
/// Swaps two shared libraries. Does not invalidate symbols and functions loaded from libraries. Throws nothing.
|
||||
inline void swap(smart_library& lhs, smart_library& rhs) BOOST_NOEXCEPT {
|
||||
inline void swap(smart_library& lhs, smart_library& rhs) noexcept {
|
||||
lhs.swap(rhs);
|
||||
}
|
||||
|
||||
@@ -439,14 +430,14 @@ void get(const smart_library& sm, const std::string &name);
|
||||
#endif
|
||||
|
||||
template<class T>
|
||||
typename boost::enable_if<boost::is_object<T>, T&>::type get(const smart_library& sm, const std::string &name)
|
||||
typename std::enable_if<std::is_object<T>::value, T&>::type get(const smart_library& sm, const std::string &name)
|
||||
|
||||
{
|
||||
return sm.get_variable<T>(name);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
typename boost::enable_if<boost::is_function<T>, T&>::type get(const smart_library& sm, const std::string &name)
|
||||
typename std::enable_if<std::is_function<T>::value, T&>::type get(const smart_library& sm, const std::string &name)
|
||||
{
|
||||
return sm.get_function<T>(name);
|
||||
}
|
||||
|
||||
@@ -99,6 +99,7 @@ project
|
||||
[ compile-fail section_name_too_big.cpp ]
|
||||
[ run shared_library_concurrent_load_test.cpp /boost/thread//boost_thread : : library1 library2 my_plugin_aggregator refcounting_plugin : <link>shared ]
|
||||
[ run cpp_mangle_test.cpp : : cpp_plugin ]
|
||||
[ run cpp_mangling.cpp ]
|
||||
[ run cpp_load_test.cpp : : cpp_plugin ]
|
||||
[ run cpp_import_test.cpp : : cpp_plugin ]
|
||||
[ run template_method_linux_test.cpp : : cpp_plugin ]
|
||||
|
||||
@@ -21,7 +21,7 @@ init:
|
||||
# From this point and below code is same for all the Boost libs
|
||||
###############################################################################################################
|
||||
|
||||
version: 1.64.{build}-{branch}
|
||||
version: 1.87.{build}-{branch}
|
||||
|
||||
# branches to build
|
||||
branches:
|
||||
@@ -63,10 +63,11 @@ environment:
|
||||
# ADDPATH: C:\cygwin64\bin;
|
||||
# TOOLSET: gcc
|
||||
# CXXSTD: 11,14,1z
|
||||
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
|
||||
ADDPATH: C:\mingw\bin;
|
||||
TOOLSET: gcc
|
||||
CXXSTD: 11,14,1z
|
||||
# MinGW 32 bit is not supported by boost system any more
|
||||
#- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
|
||||
# ADDPATH: C:\mingw\bin;
|
||||
# TOOLSET: gcc
|
||||
# CXXSTD: 11,14,1z
|
||||
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
|
||||
ADDPATH: C:\mingw-w64\x86_64-7.2.0-posix-seh-rt_v5-rev1\mingw64\bin;
|
||||
TOOLSET: gcc
|
||||
|
||||
@@ -8,8 +8,6 @@
|
||||
|
||||
#include <boost/config.hpp>
|
||||
|
||||
#if (__cplusplus >= 201402L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 201402L)
|
||||
|
||||
#include <boost/dll/config.hpp>
|
||||
#include <string>
|
||||
|
||||
@@ -138,4 +136,3 @@ cpp_plugin_type_pasrser::type_test(
|
||||
{}
|
||||
} // namespace space
|
||||
|
||||
#endif
|
||||
|
||||
@@ -9,8 +9,6 @@
|
||||
|
||||
#include <boost/config.hpp>
|
||||
|
||||
#if (__cplusplus >= 201402L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 201402L)
|
||||
|
||||
#include "../example/b2_workarounds.hpp"
|
||||
|
||||
#include <iostream>
|
||||
@@ -24,7 +22,7 @@ using namespace std;
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
#include <boost/filesystem.hpp>
|
||||
#include <boost/variant.hpp>
|
||||
#include <boost/function.hpp>
|
||||
#include <functional>
|
||||
|
||||
#define L cout << __LINE__ << endl;
|
||||
|
||||
@@ -92,7 +90,7 @@ int main(int argc, char* argv[])
|
||||
BOOST_TEST((cl->*fun2)(5 ,2 ) == 7 );
|
||||
|
||||
//test if it binds.
|
||||
boost::function<int(override_class* const, int, int)> mem_fn_obj = func;
|
||||
std::function<int(override_class* const, int, int)> mem_fn_obj = func;
|
||||
|
||||
|
||||
const std::type_info & ti = cl.get_type_info();
|
||||
@@ -109,7 +107,3 @@ int main(int argc, char* argv[])
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
||||
|
||||
#else
|
||||
int main() {return 0;}
|
||||
#endif
|
||||
|
||||
@@ -8,8 +8,6 @@
|
||||
|
||||
#include <boost/config.hpp>
|
||||
|
||||
#if (__cplusplus >= 201402L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 201402L)
|
||||
|
||||
#include "../example/b2_workarounds.hpp"
|
||||
|
||||
#include <boost/dll/smart_library.hpp>
|
||||
@@ -18,8 +16,8 @@
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
#include <boost/filesystem.hpp>
|
||||
#include <boost/variant.hpp>
|
||||
#include <boost/function.hpp>
|
||||
|
||||
#include <functional>
|
||||
#include <iostream>
|
||||
|
||||
struct override_class
|
||||
@@ -51,7 +49,7 @@ int main(int argc, char* argv[])
|
||||
ovl(5.0);
|
||||
BOOST_TEST(*sp_variable == 5.0);
|
||||
|
||||
boost::function<void(int)> f_test = ovl;//test if it binds
|
||||
std::function<void(int)> f_test = ovl;//test if it binds
|
||||
f_test(-2);
|
||||
BOOST_TEST(*unscoped_var == -2);
|
||||
|
||||
@@ -76,6 +74,3 @@ int main(int argc, char* argv[])
|
||||
return boost::report_errors();
|
||||
}
|
||||
|
||||
#else
|
||||
int main() {return 0;}
|
||||
#endif
|
||||
|
||||
@@ -10,12 +10,7 @@
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/predef.h>
|
||||
|
||||
#if (__cplusplus >= 201103L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 201103L)
|
||||
// Make sure that it at least compiles
|
||||
# include <boost/dll/smart_library.hpp>
|
||||
#endif
|
||||
|
||||
#if (__cplusplus >= 201402L) || (BOOST_COMP_MSVC >= BOOST_VERSION_NUMBER(14,0,0))
|
||||
|
||||
#include "../example/b2_workarounds.hpp"
|
||||
|
||||
@@ -231,7 +226,3 @@ int main(int argc, char* argv[])
|
||||
std::cerr << 28 << ' ';
|
||||
return boost::report_errors();
|
||||
}
|
||||
|
||||
#else
|
||||
int main() {return 0;}
|
||||
#endif
|
||||
|
||||
@@ -8,8 +8,6 @@
|
||||
|
||||
#include <boost/config.hpp>
|
||||
|
||||
#if (__cplusplus >= 201402L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 201402L)
|
||||
|
||||
#include "../example/b2_workarounds.hpp"
|
||||
|
||||
#include <boost/dll/smart_library.hpp>
|
||||
@@ -128,6 +126,3 @@ int main(int argc, char* argv[])
|
||||
return boost::report_errors();
|
||||
}
|
||||
|
||||
#else
|
||||
int main() {return 0;}
|
||||
#endif
|
||||
|
||||
155
test/cpp_mangling.cpp
Normal file
155
test/cpp_mangling.cpp
Normal file
@@ -0,0 +1,155 @@
|
||||
// Copyright 2024 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)
|
||||
|
||||
// For more information, see http://www.boost.org
|
||||
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
|
||||
#include <boost/dll/detail/demangling/msvc.hpp>
|
||||
|
||||
int main() {
|
||||
namespace parser = boost::dll::detail::parser;
|
||||
|
||||
BOOST_TEST(parser::is_destructor_with_name("foo::~foo(void)")("public: __cdecl foo::~foo(void)"));
|
||||
BOOST_TEST(parser::is_destructor_with_name("foo::~foo(void)")("private: __cdecl foo::~foo(void)"));
|
||||
BOOST_TEST(parser::is_destructor_with_name("foo::~foo(void)")("protected: __cdecl foo::~foo(void)"));
|
||||
|
||||
BOOST_TEST(parser::is_destructor_with_name("foo::~foo(void)")("public: virtual __cdecl foo::~foo(void)"));
|
||||
BOOST_TEST(parser::is_destructor_with_name("foo::~foo(void)")("private: virtual __cdecl foo::~foo(void)"));
|
||||
BOOST_TEST(parser::is_destructor_with_name("foo::~foo(void)")("protected: virtual __cdecl foo::~foo(void)"));
|
||||
|
||||
BOOST_TEST(parser::is_destructor_with_name("foo::~foo(void)")("public: __cdecl foo::~foo(void) __ptr64"));
|
||||
BOOST_TEST(parser::is_destructor_with_name("foo::~foo(void)")("private: __cdecl foo::~foo(void) __ptr64"));
|
||||
BOOST_TEST(parser::is_destructor_with_name("foo::~foo(void)")("protected: __cdecl foo::~foo(void) __ptr64"));
|
||||
|
||||
BOOST_TEST(parser::is_destructor_with_name("some_space::some_father::~some_father(void)")("public: __cdecl some_space::some_father::~some_father(void) __ptr64"));
|
||||
|
||||
BOOST_TEST(parser::is_destructor_with_name("foo::~foo(void)")("public: __thiscall foo::~foo(void)"));
|
||||
BOOST_TEST(parser::is_destructor_with_name("foo::~foo(void)")("private: __thiscall foo::~foo(void)"));
|
||||
BOOST_TEST(parser::is_destructor_with_name("foo::~foo(void)")("protected: __thiscall foo::~foo(void)"));
|
||||
|
||||
BOOST_TEST(parser::is_destructor_with_name("foo::~foo(void)")("public: virtual __thiscall foo::~foo(void)"));
|
||||
BOOST_TEST(parser::is_destructor_with_name("foo::~foo(void)")("private: virtual __thiscall foo::~foo(void)"));
|
||||
BOOST_TEST(parser::is_destructor_with_name("foo::~foo(void)")("protected: virtual __thiscall foo::~foo(void)"));
|
||||
|
||||
BOOST_TEST(parser::is_destructor_with_name("foo::~foo(void)")("public: __thiscall foo::~foo(void) __ptr32"));
|
||||
BOOST_TEST(parser::is_destructor_with_name("foo::~foo(void)")("private: __thiscall foo::~foo(void) __ptr32"));
|
||||
BOOST_TEST(parser::is_destructor_with_name("foo::~foo(void)")("protected: __thiscall foo::~foo(void) __ptr32"));
|
||||
|
||||
BOOST_TEST(parser::is_destructor_with_name("some_space::some_father::~some_father(void)")("public: __thiscall some_space::some_father::~some_father(void) __ptr64"));
|
||||
|
||||
|
||||
boost::dll::detail::mangled_storage_impl ms;
|
||||
{
|
||||
void(*ptr0)(int) = nullptr;
|
||||
boost::core::string_view s = "integer";
|
||||
BOOST_TEST(parser::try_consume_arg_list(s, ms, ptr0));
|
||||
BOOST_TEST_EQ(s, "eger");
|
||||
}
|
||||
{
|
||||
void(*ptr1)(int) = nullptr;
|
||||
boost::core::string_view s = "int";
|
||||
BOOST_TEST(parser::try_consume_arg_list(s, ms, ptr1));
|
||||
BOOST_TEST(s.empty());
|
||||
}
|
||||
{
|
||||
void(*ptr2)() = nullptr;
|
||||
boost::core::string_view s = "void";
|
||||
BOOST_TEST(parser::try_consume_arg_list(s, ms, ptr2));
|
||||
BOOST_TEST(s.empty());
|
||||
}
|
||||
{
|
||||
void(*ptr3)(int,int) = nullptr;
|
||||
boost::core::string_view s = "int,int";
|
||||
BOOST_TEST(parser::try_consume_arg_list(s, ms, ptr3));
|
||||
BOOST_TEST(s.empty());
|
||||
}
|
||||
{
|
||||
void(*ptr4)(int,int,int) = nullptr;
|
||||
boost::core::string_view s = "int,int,int";
|
||||
BOOST_TEST(parser::try_consume_arg_list(s, ms, ptr4));
|
||||
BOOST_TEST(s.empty());
|
||||
}
|
||||
|
||||
|
||||
BOOST_TEST((
|
||||
parser::is_constructor_with_name<void(*)()>("some_space::some_class::some_class", ms)
|
||||
("public: __cdecl some_space::some_class::some_class(void) __ptr64")
|
||||
));
|
||||
BOOST_TEST((
|
||||
parser::is_constructor_with_name<void(*)(int)>("some_space::some_class::some_class", ms)
|
||||
("private: __cdecl some_space::some_class::some_class(int)")
|
||||
));
|
||||
BOOST_TEST((
|
||||
parser::is_constructor_with_name<void(*)(int,int)>("some_space::some_class::some_class", ms)
|
||||
("private: __cdecl some_space::some_class::some_class(int,int)")
|
||||
));
|
||||
|
||||
|
||||
BOOST_TEST((
|
||||
parser::is_variable_with_name<int>("some_space::some_class::value", ms)
|
||||
("public: static int some_space::some_class::value")
|
||||
));
|
||||
|
||||
BOOST_TEST((
|
||||
parser::is_variable_with_name<int>("some_space::some_class::value", ms)
|
||||
("int some_space::some_class::value")
|
||||
));
|
||||
|
||||
BOOST_TEST((
|
||||
parser::is_variable_with_name<double>("some_space::variable", ms)
|
||||
("public: static double some_space::variable")
|
||||
));
|
||||
|
||||
BOOST_TEST((
|
||||
!parser::is_variable_with_name<double>("some_space::variable", ms)
|
||||
("public: static int some_space::variable_that_is_not_exist")
|
||||
));
|
||||
|
||||
BOOST_TEST((
|
||||
parser::is_variable_with_name<const double>("unscoped_c_var", ms)
|
||||
("double const unscoped_c_var")
|
||||
));
|
||||
|
||||
|
||||
BOOST_TEST((
|
||||
parser::is_function_with_name<void(*)(int)>("overloaded", ms)
|
||||
("void __cdecl overloaded(int)")
|
||||
));
|
||||
|
||||
BOOST_TEST((
|
||||
parser::is_function_with_name<void(*)(double)>("overloaded", ms)
|
||||
("void __cdecl overloaded(double)")
|
||||
));
|
||||
|
||||
BOOST_TEST((
|
||||
parser::is_function_with_name<const int&(*)()>("some_space::scoped_fun", ms)
|
||||
("int const & __ptr64 __cdecl some_space::scoped_fun(void)")
|
||||
));
|
||||
|
||||
|
||||
BOOST_TEST((
|
||||
parser::is_mem_fn_with_name<volatile int, int(*)(int,int)>("func", ms)
|
||||
("public: int __thiscall int::func(int,int)volatile ")
|
||||
));
|
||||
BOOST_TEST((
|
||||
parser::is_mem_fn_with_name<const volatile int, double(*)(double)>("func", ms)
|
||||
("private: double __thiscall int::func(double)const volatile ")
|
||||
));
|
||||
|
||||
BOOST_TEST((
|
||||
parser::is_mem_fn_with_name<volatile int, int(*)(int,int)>("func", ms)
|
||||
("public: int __cdecl int::func(int,int)volatile __ptr64")
|
||||
));
|
||||
|
||||
BOOST_TEST((
|
||||
parser::is_mem_fn_with_name<volatile int, int(*)(int,int)>("func", ms)
|
||||
("public: virtual int __cdecl int::func(int,int)volatile __ptr64")
|
||||
));
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
||||
|
||||
@@ -9,8 +9,6 @@
|
||||
|
||||
#include <boost/config.hpp>
|
||||
|
||||
#if (__cplusplus >= 201402L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 201402L)
|
||||
|
||||
#include <boost/dll/config.hpp>
|
||||
#include <boost/variant.hpp>
|
||||
|
||||
@@ -198,6 +196,3 @@ namespace space {
|
||||
template BOOST_SYMBOL_EXPORT int my_plugin::Func2<::space::my_plugin>();
|
||||
template BOOST_SYMBOL_EXPORT int my_plugin::AFunc<::space::my_plugin>();
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
|
||||
#include <boost/config.hpp>
|
||||
|
||||
#if (__cplusplus >= 201402L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 201402L)
|
||||
#include "../example/b2_workarounds.hpp"
|
||||
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
@@ -165,10 +164,3 @@ main(int argc, char* argv[])
|
||||
return boost::report_errors();
|
||||
}
|
||||
|
||||
#else
|
||||
int
|
||||
main()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -39,7 +39,8 @@ int main(int argc, char* argv[])
|
||||
#if defined(__GNUC__) && __GNUC__ >= 4 && defined(__ELF__)
|
||||
BOOST_TEST(std::find(symb.begin(), symb.end(), "protected_function") != symb.end());
|
||||
#endif
|
||||
|
||||
|
||||
std::cout << "\n\n'boostdll' symbols:\n";
|
||||
symb = lib_info.symbols("boostdll");
|
||||
std::copy(symb.begin(), symb.end(), std::ostream_iterator<std::string>(std::cout, "\n"));
|
||||
BOOST_TEST(std::find(symb.begin(), symb.end(), "const_integer_g_alias") != symb.end());
|
||||
@@ -48,6 +49,7 @@ int main(int argc, char* argv[])
|
||||
BOOST_TEST(std::find(symb.begin(), symb.end(), "say_hello") == symb.end());
|
||||
BOOST_TEST(lib_info.symbols(std::string("boostdll")) == symb);
|
||||
|
||||
std::cout << "\n\n'empty' symbols:\n";
|
||||
std::vector<std::string> empty = lib_info.symbols("empty");
|
||||
BOOST_TEST(empty.empty() == true);
|
||||
|
||||
|
||||
@@ -9,13 +9,8 @@
|
||||
|
||||
#include <boost/config.hpp>
|
||||
|
||||
#if (__cplusplus >= 201402L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 201402L)
|
||||
|
||||
#include <boost/dll/smart_library.hpp>
|
||||
#include <boost/dll/import_mangled.hpp>
|
||||
#include <boost/dll/import_class.hpp>
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#include <boost/dll.hpp>
|
||||
|
||||
@@ -12,7 +12,6 @@
|
||||
#include <boost/dll/shared_library.hpp>
|
||||
#include <boost/dll/library_info.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
#include <boost/function.hpp>
|
||||
|
||||
|
||||
// Unit Tests
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
#include "../example/b2_workarounds.hpp"
|
||||
#include <boost/dll.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
#include <boost/function.hpp>
|
||||
#include <functional>
|
||||
#include <boost/fusion/container.hpp>
|
||||
// lib functions
|
||||
|
||||
@@ -35,7 +35,7 @@ void refcountable_test(boost::dll::fs::path shared_library_path) {
|
||||
std::vector<int> v(1000);
|
||||
|
||||
{
|
||||
boost::function<say_hello_func> sz2
|
||||
std::function<say_hello_func> sz2
|
||||
= import_symbol<say_hello_func>(shared_library_path, "say_hello");
|
||||
|
||||
sz2();
|
||||
@@ -52,17 +52,17 @@ void refcountable_test(boost::dll::fs::path shared_library_path) {
|
||||
#endif
|
||||
|
||||
{
|
||||
boost::function<std::size_t(const std::vector<int>&)> sz
|
||||
std::function<std::size_t(const std::vector<int>&)> sz
|
||||
= import_alias<std::size_t(const std::vector<int>&)>(shared_library_path, "foo_bar");
|
||||
BOOST_TEST(sz(v) == 1000);
|
||||
}
|
||||
|
||||
|
||||
{
|
||||
boost::function<do_share_t> f;
|
||||
std::function<do_share_t> f;
|
||||
|
||||
{
|
||||
boost::function<do_share_t> f2 = import_alias<do_share_t>(shared_library_path, "do_share");
|
||||
std::function<do_share_t> f2 = import_alias<do_share_t>(shared_library_path, "do_share");
|
||||
f = f2;
|
||||
}
|
||||
|
||||
@@ -91,13 +91,13 @@ void refcountable_test(boost::dll::fs::path shared_library_path) {
|
||||
}
|
||||
|
||||
{
|
||||
boost::function<int&()> f = import_alias<int&()>(shared_library_path, "ref_returning_function");
|
||||
std::function<int&()> f = import_alias<int&()>(shared_library_path, "ref_returning_function");
|
||||
BOOST_TEST(f() == 0);
|
||||
|
||||
f() = 10;
|
||||
BOOST_TEST(f() == 10);
|
||||
|
||||
boost::function<int&()> f1 = import_alias<int&()>(shared_library_path, "ref_returning_function");
|
||||
std::function<int&()> f1 = import_alias<int&()>(shared_library_path, "ref_returning_function");
|
||||
BOOST_TEST(f1() == 10);
|
||||
|
||||
f1() += 10;
|
||||
@@ -157,7 +157,7 @@ int main(int argc, char* argv[]) {
|
||||
|
||||
BOOST_TEST(sl.get<const int>("const_integer_g") == 777);
|
||||
|
||||
boost::function<int(int)> inc = sl.get<int(int)>("increment");
|
||||
std::function<int(int)> inc = sl.get<int(int)>("increment");
|
||||
BOOST_TEST(inc(1) == 2);
|
||||
BOOST_TEST(inc(2) == 3);
|
||||
BOOST_TEST(inc(3) == 4);
|
||||
@@ -170,7 +170,7 @@ int main(int argc, char* argv[]) {
|
||||
|
||||
|
||||
// Checking aliases
|
||||
boost::function<std::size_t(const std::vector<int>&)> sz
|
||||
std::function<std::size_t(const std::vector<int>&)> sz
|
||||
= sl.get_alias<std::size_t(const std::vector<int>&)>("foo_bar");
|
||||
|
||||
std::vector<int> v(10);
|
||||
|
||||
@@ -9,6 +9,11 @@
|
||||
|
||||
#include "../example/b2_workarounds.hpp"
|
||||
#include <boost/dll.hpp>
|
||||
|
||||
#include <system_error>
|
||||
#include <boost/system/error_code.hpp>
|
||||
#include <boost/system/system_error.hpp>
|
||||
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
// Unit Tests
|
||||
|
||||
@@ -403,7 +408,8 @@ int main(int argc, char* argv[])
|
||||
std::cout << "\nLibrary location: " << sl.location();
|
||||
BOOST_TEST( boost::dll::fs::equivalent(sl.location(), program_location()) );
|
||||
|
||||
boost::dll::fs::error_code ec;
|
||||
// Make sure that works with boost::system::error_code
|
||||
boost::system::error_code ec;
|
||||
shared_library sl2(program_location());
|
||||
BOOST_TEST(sl2.is_loaded());
|
||||
BOOST_TEST( boost::dll::fs::equivalent(sl2.location(), program_location()) );
|
||||
@@ -478,7 +484,7 @@ int main(int argc, char* argv[])
|
||||
|
||||
|
||||
{ // error_code load calls test
|
||||
boost::dll::fs::error_code ec;
|
||||
std::error_code ec;
|
||||
shared_library sl(shared_library_path / "dir_that_does_not_exist", ec);
|
||||
BOOST_TEST(ec);
|
||||
BOOST_TEST(!sl.is_loaded());
|
||||
@@ -512,6 +518,75 @@ int main(int argc, char* argv[])
|
||||
BOOST_TEST(!sl);
|
||||
}
|
||||
|
||||
{ // error_code load calls test
|
||||
std::error_code ec; // make sure that works with std::error_code
|
||||
shared_library sl(shared_library_path / "dir_that_does_not_exist", ec);
|
||||
BOOST_TEST(ec);
|
||||
BOOST_TEST(!sl.is_loaded());
|
||||
BOOST_TEST(!sl);
|
||||
|
||||
boost::dll::fs::path bad_path(shared_library_path);
|
||||
bad_path += ".1.1.1.1.1.1";
|
||||
sl.load(bad_path, ec);
|
||||
BOOST_TEST(ec);
|
||||
BOOST_TEST(!sl.is_loaded());
|
||||
BOOST_TEST(!sl);
|
||||
|
||||
sl.load(shared_library_path, ec);
|
||||
BOOST_TEST(!ec);
|
||||
BOOST_TEST(sl.is_loaded());
|
||||
BOOST_TEST(sl);
|
||||
|
||||
shared_library sl2(bad_path, ec);
|
||||
BOOST_TEST(ec);
|
||||
BOOST_TEST(!sl2.is_loaded());
|
||||
BOOST_TEST(!sl2);
|
||||
|
||||
shared_library sl3(shared_library_path, ec);
|
||||
BOOST_TEST(!ec);
|
||||
BOOST_TEST(sl3.is_loaded());
|
||||
BOOST_TEST(sl3);
|
||||
|
||||
sl.load("", ec);
|
||||
BOOST_TEST(ec);
|
||||
BOOST_TEST(!sl.is_loaded());
|
||||
BOOST_TEST(!sl);
|
||||
}
|
||||
|
||||
{ // error_code load calls test
|
||||
boost::system::error_code ec; // make sure that works with boost::system::error_code
|
||||
shared_library sl(shared_library_path / "dir_that_does_not_exist", ec);
|
||||
BOOST_TEST(ec);
|
||||
BOOST_TEST(!sl.is_loaded());
|
||||
BOOST_TEST(!sl);
|
||||
|
||||
boost::dll::fs::path bad_path(shared_library_path);
|
||||
bad_path += ".1.1.1.1.1.1";
|
||||
sl.load(bad_path, ec);
|
||||
BOOST_TEST(ec);
|
||||
BOOST_TEST(!sl.is_loaded());
|
||||
BOOST_TEST(!sl);
|
||||
|
||||
sl.load(shared_library_path, ec);
|
||||
BOOST_TEST(!ec);
|
||||
BOOST_TEST(sl.is_loaded());
|
||||
BOOST_TEST(sl);
|
||||
|
||||
shared_library sl2(bad_path, ec);
|
||||
BOOST_TEST(ec);
|
||||
BOOST_TEST(!sl2.is_loaded());
|
||||
BOOST_TEST(!sl2);
|
||||
|
||||
shared_library sl3(shared_library_path, ec);
|
||||
BOOST_TEST(!ec);
|
||||
BOOST_TEST(sl3.is_loaded());
|
||||
BOOST_TEST(sl3);
|
||||
|
||||
sl.load("", ec);
|
||||
BOOST_TEST(ec);
|
||||
BOOST_TEST(!sl.is_loaded());
|
||||
BOOST_TEST(!sl);
|
||||
}
|
||||
|
||||
shared_library_path = do_find_correct_libs_path(argc, argv, "library1");
|
||||
fs_copy_guard guard(shared_library_path);
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
// or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#if (__cplusplus >= 201402L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 201402L)
|
||||
|
||||
#include <boost/dll/smart_library.hpp>
|
||||
#include <boost/dll/import_mangled.hpp>
|
||||
@@ -60,8 +59,3 @@ int main(int argc, char** argv) {
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
||||
|
||||
|
||||
#else
|
||||
int main() {}
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user