summaryrefslogtreecommitdiffstats
path: root/src/boost/libs/dll
diff options
context:
space:
mode:
Diffstat (limited to 'src/boost/libs/dll')
-rw-r--r--src/boost/libs/dll/README.md20
-rw-r--r--src/boost/libs/dll/example/b2_workarounds.hpp109
-rw-r--r--src/boost/libs/dll/example/getting_started.cpp83
-rw-r--r--src/boost/libs/dll/example/getting_started_library.cpp70
-rw-r--r--src/boost/libs/dll/example/mangled/import_class.cpp47
-rw-r--r--src/boost/libs/dll/example/mangled/my_cpp_plugin.hpp43
-rw-r--r--src/boost/libs/dll/example/mangled/smart_lib.cpp58
-rw-r--r--src/boost/libs/dll/example/tutorial1/my_plugin_sum.cpp43
-rw-r--r--src/boost/libs/dll/example/tutorial1/tutorial1.cpp31
-rw-r--r--src/boost/libs/dll/example/tutorial2/my_plugin_aggregator.cpp52
-rw-r--r--src/boost/libs/dll/example/tutorial2/tutorial2.cpp36
-rw-r--r--src/boost/libs/dll/example/tutorial3/tutorial3.cpp56
-rw-r--r--src/boost/libs/dll/example/tutorial4/load_self.cpp39
-rw-r--r--src/boost/libs/dll/example/tutorial4/static_plugin.cpp42
-rw-r--r--src/boost/libs/dll/example/tutorial4/static_plugin.hpp22
-rw-r--r--src/boost/libs/dll/example/tutorial5/load_all.cpp146
-rw-r--r--src/boost/libs/dll/example/tutorial6/on_unload_lib.cpp48
-rw-r--r--src/boost/libs/dll/example/tutorial6/tutorial6.cpp39
-rw-r--r--src/boost/libs/dll/example/tutorial7/library1.cpp21
-rw-r--r--src/boost/libs/dll/example/tutorial7/library2.cpp26
-rw-r--r--src/boost/libs/dll/example/tutorial7/tutorial7.cpp48
-rw-r--r--src/boost/libs/dll/example/tutorial8/refcounting_api.hpp77
-rw-r--r--src/boost/libs/dll/example/tutorial8/refcounting_plugin.cpp47
-rw-r--r--src/boost/libs/dll/example/tutorial8/refcounting_plugin.hpp17
-rw-r--r--src/boost/libs/dll/example/tutorial8/tutorial8.cpp25
-rw-r--r--src/boost/libs/dll/example/tutorial8/tutorial8_static.cpp23
-rw-r--r--src/boost/libs/dll/example/tutorial9/tutorial9.cpp60
-rw-r--r--src/boost/libs/dll/example/tutorial_common/my_plugin_api.hpp24
-rw-r--r--src/boost/libs/dll/index.html35
-rw-r--r--src/boost/libs/dll/meta/libraries.json15
-rw-r--r--src/boost/libs/dll/test/Jamfile.v295
-rw-r--r--src/boost/libs/dll/test/cpp_import_class_test.cpp115
-rw-r--r--src/boost/libs/dll/test/cpp_import_test.cpp81
-rw-r--r--src/boost/libs/dll/test/cpp_load_test.cpp228
-rw-r--r--src/boost/libs/dll/test/cpp_mangle_test.cpp133
-rw-r--r--src/boost/libs/dll/test/cpp_test_library.cpp203
-rw-r--r--src/boost/libs/dll/test/library_info_test.cpp65
-rw-r--r--src/boost/libs/dll/test/link.hpp21
-rw-r--r--src/boost/libs/dll/test/link1.cpp10
-rw-r--r--src/boost/libs/dll/test/link2.cpp12
-rw-r--r--src/boost/libs/dll/test/section_name_too_big.cpp17
-rw-r--r--src/boost/libs/dll/test/shared_library_concurrent_load_test.cpp82
-rw-r--r--src/boost/libs/dll/test/shared_library_errors.cpp100
-rw-r--r--src/boost/libs/dll/test/shared_library_get_symbol_test.cpp193
-rw-r--r--src/boost/libs/dll/test/shared_library_load_test.cpp528
-rw-r--r--src/boost/libs/dll/test/shared_library_search_symbol_test.cpp49
-rw-r--r--src/boost/libs/dll/test/structures_tests.cpp345
-rw-r--r--src/boost/libs/dll/test/symbol_runtime_info_test.cpp231
-rw-r--r--src/boost/libs/dll/test/template_method_linux_test.cpp67
-rw-r--r--src/boost/libs/dll/test/test_library.cpp115
50 files changed, 4092 insertions, 0 deletions
diff --git a/src/boost/libs/dll/README.md b/src/boost/libs/dll/README.md
new file mode 100644
index 000000000..f21db0331
--- /dev/null
+++ b/src/boost/libs/dll/README.md
@@ -0,0 +1,20 @@
+# [Boost Dynamic Library Load (Boost.DLL)](http://boost.org/libs/dll)
+
+Boost.DLL is a part of the [Boost C++ Libraries](http://github.com/boostorg). It is a library for comfortable work with DLL and DSO.
+
+### Test results
+
+Branches | Build | Tests coverage | More info
+----------------|-------------- | -------------- |-----------
+Develop: | [![Build Status](https://travis-ci.org/apolukhin/Boost.DLL.svg?branch=develop)](https://travis-ci.org/apolukhin/Boost.DLL) [![Build status](https://ci.appveyor.com/api/projects/status/t6q6yhcabtk5b99l/branch/develop?svg=true)](https://ci.appveyor.com/project/apolukhin/boost-dll/branch/develop) | [![Coverage Status](https://coveralls.io/repos/apolukhin/Boost.DLL/badge.png?branch=develop)](https://coveralls.io/r/apolukhin/Boost.DLL?branch=develop) | [details...](http://www.boost.org/development/tests/develop/developer/dll.html)
+Master: | [![Build Status](https://travis-ci.org/apolukhin/Boost.DLL.svg?branch=master)](https://travis-ci.org/apolukhin/Boost.DLL) [![Build status](https://ci.appveyor.com/api/projects/status/t6q6yhcabtk5b99l/branch/master?svg=true)](https://ci.appveyor.com/project/apolukhin/boost-dll/branch/master) | [![Coverage Status](https://coveralls.io/repos/apolukhin/Boost.DLL/badge.png?branch=master)](https://coveralls.io/r/apolukhin/Boost.DLL?branch=master) | [details...](http://www.boost.org/development/tests/master/developer/dll.html)
+
+[Open Issues](https://svn.boost.org/trac/boost/query?status=!closed&component=dll)
+
+[Latest developer documentation](http://apolukhin.github.io/Boost.DLL/index.html)
+
+### About
+This library was derived from the [Boost.Application](https://github.com/retf/Boost.Application) library.
+
+### License
+Distributed under the [Boost Software License, Version 1.0](http://www.boost.org/LICENSE_1_0.txt).
diff --git a/src/boost/libs/dll/example/b2_workarounds.hpp b/src/boost/libs/dll/example/b2_workarounds.hpp
new file mode 100644
index 000000000..bb9f8ae56
--- /dev/null
+++ b/src/boost/libs/dll/example/b2_workarounds.hpp
@@ -0,0 +1,109 @@
+// Copyright 2014 Renato Tegon Forti, Antony Polukhin.
+// Copyright 2015-2019 Antony Polukhin.
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt
+// or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_DLL_EXAMPLE_COMMON_B2_WORKAROUNDS_HPP
+#define BOOST_DLL_EXAMPLE_COMMON_B2_WORKAROUNDS_HPP
+
+#include <boost/dll/config.hpp>
+#include <boost/filesystem.hpp>
+#include <boost/system/error_code.hpp>
+#include <iostream>
+#include <cctype>
+
+namespace b2_workarounds {
+
+
+inline boost::filesystem::path drop_version(const boost::filesystem::path& lhs) {
+ boost::filesystem::path ext = lhs.filename().extension();
+ if (ext.native().size() > 1 && std::isdigit(ext.string()[1])) {
+ ext = lhs;
+ ext.replace_extension().replace_extension().replace_extension();
+ return ext;
+ }
+
+ return lhs;
+}
+
+inline bool is_shared_library(const std::string& s) {
+ return (s.find(".dll") != std::string::npos || s.find(".so") != std::string::npos || s.find(".dylib") != std::string::npos)
+ && s.find(".lib") == std::string::npos
+ && s.find(".exp") == std::string::npos
+ && s.find(".pdb") == std::string::npos
+ && s.find(".manifest") == std::string::npos
+ && s.find(".rsp") == std::string::npos
+ && s.find(".obj") == std::string::npos
+ && s.find(".a") == std::string::npos;
+}
+
+inline bool is_shared_library(const char* p) {
+ return b2_workarounds::is_shared_library(std::string(p));
+}
+
+inline bool is_shared_library(const boost::filesystem::path& p) {
+ return b2_workarounds::is_shared_library(p.string());
+}
+
+inline boost::dll::fs::path first_lib_from_argv(int argc, char* argv[]) {
+ BOOST_ASSERT(argc > 1);
+ (void)argc;
+
+ for (int i = 1; i < argc; ++i) {
+ if (b2_workarounds::is_shared_library(argv[i])) {
+ return argv[i];
+ }
+
+ std::cout << "b2_workarounds::first_lib_from_argv(argc, argv): skipping '" << argv[i] << "'" << std::endl;
+ }
+
+ BOOST_ASSERT(false);
+ return argv[1];
+}
+
+// This ugly struct is required to drop library version from shared library generated by b2.
+struct argv_to_path_guard {
+ const boost::filesystem::path original_;
+ const boost::filesystem::path version_dropped_;
+ const std::string just_path_;
+ const bool same_;
+
+
+ static inline boost::filesystem::path drop_b2_deco(const boost::filesystem::path& in) {
+ std::size_t pos = in.filename().string().find("-");
+ boost::filesystem::path res = in.parent_path() / in.filename().string().substr(0, in.filename().string().find("-"));
+ if (pos != std::string::npos) {
+ res += in.extension();
+ }
+ return res;
+ }
+
+ inline explicit argv_to_path_guard(int argc, char* argv[])
+ : original_(first_lib_from_argv(argc, argv))
+ , version_dropped_( drop_b2_deco(drop_version(original_)) )
+ , just_path_( version_dropped_.parent_path().string() )
+ , same_(version_dropped_ == original_)
+ {
+ if (!same_) {
+ boost::system::error_code ignore;
+ boost::filesystem::remove(version_dropped_, ignore);
+ boost::filesystem::copy(original_, version_dropped_, ignore);
+ }
+
+ argv[1] = const_cast<char*>(just_path_.c_str());
+ }
+
+ inline ~argv_to_path_guard() {
+ if (!same_) {
+ boost::system::error_code ignore;
+ boost::filesystem::remove(version_dropped_, ignore);
+ }
+ }
+};
+
+} // namespace b2_workarounds
+
+#endif // BOOST_DLL_EXAMPLE_COMMON_B2_WORKAROUNDS_HPP
+
diff --git a/src/boost/libs/dll/example/getting_started.cpp b/src/boost/libs/dll/example/getting_started.cpp
new file mode 100644
index 000000000..4d634662a
--- /dev/null
+++ b/src/boost/libs/dll/example/getting_started.cpp
@@ -0,0 +1,83 @@
+// Copyright 2014 Renato Tegon Forti, Antony Polukhin.
+// Copyright 2015-2019 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)
+
+#include <boost/core/lightweight_test.hpp>
+#include <boost/dll.hpp>
+#include <boost/function.hpp>
+#include <string>
+#include "b2_workarounds.hpp"
+
+// Unit Tests
+int main(int argc, char* argv[]) {
+ using namespace boost;
+
+ boost::dll::fs::path path_to_shared_library = b2_workarounds::first_lib_from_argv(argc, argv);
+ BOOST_TEST(path_to_shared_library.string().find("getting_started_library") != std::string::npos);
+
+ //[getting_started_imports_c_function
+ // Importing pure C function
+ function<int(int)> c_func = dll::import<int(int)>(
+ path_to_shared_library, "c_func_name"
+ );
+ //]
+
+ int c_func_res = c_func(1); // calling the function
+ BOOST_TEST(c_func_res == 2);
+
+
+ //[getting_started_imports_c_variable
+ // Importing pure C variable
+ shared_ptr<int> c_var = dll::import<int>(
+ path_to_shared_library, "c_variable_name"
+ );
+ //]
+
+ int c_var_old_contents = *c_var; // using the variable
+ *c_var = 100;
+ BOOST_TEST(c_var_old_contents == 1);
+
+
+ //[getting_started_imports_alias
+ // Importing function by alias name
+ /*<-*/ function<std::string(const std::string&)> /*->*/ /*=auto*/ cpp_func = dll::import_alias<std::string(const std::string&)>(
+ path_to_shared_library, "pretty_name"
+ );
+ //]
+
+ // calling the function
+ std::string cpp_func_res = cpp_func(std::string("In importer."));
+ BOOST_TEST(cpp_func_res == "In importer. Hello from lib!");
+
+#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && !defined(BOOST_NO_CXX11_AUTO_DECLARATIONS)
+ //[getting_started_imports_cpp11_function
+ // Importing function.
+ auto cpp11_func = dll::import<int(std::string&&)>(
+ path_to_shared_library, "i_am_a_cpp11_function"
+ );
+ //]
+
+ // calling the function
+ int cpp11_func_res = cpp11_func(std::string("In importer."));
+ BOOST_TEST(cpp11_func_res == sizeof("In importer.") - 1);
+#endif
+
+
+ //[getting_started_imports_cpp_variable
+ // Importing variable.
+ shared_ptr<std::string> cpp_var = dll::import<std::string>(
+ path_to_shared_library, "cpp_variable_name"
+ );
+ //]
+
+ std::string cpp_var_old_contents = *cpp_var; // using the variable
+ *cpp_var = "New value";
+ BOOST_TEST(cpp_var_old_contents == "some value");
+ BOOST_TEST(*cpp_var == "New value");
+
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/dll/example/getting_started_library.cpp b/src/boost/libs/dll/example/getting_started_library.cpp
new file mode 100644
index 000000000..0264fd33b
--- /dev/null
+++ b/src/boost/libs/dll/example/getting_started_library.cpp
@@ -0,0 +1,70 @@
+// Copyright 2014 Renato Tegon Forti, Antony Polukhin.
+// Copyright 2015-2019 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)
+
+// MinGW related workaround
+#define BOOST_DLL_FORCE_ALIAS_INSTANTIATION
+
+#include <boost/dll.hpp>
+#include <string>
+
+#ifdef BOOST_NO_CXX11_NOEXCEPT
+#define noexcept
+#endif
+
+#define API extern "C" BOOST_SYMBOL_EXPORT
+
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+//[getting_started_exports_cpp11_function
+namespace some_namespace {
+ API int i_am_a_cpp11_function(std::string&& param) noexcept;
+// ^-------------------- function name to use in dll::import<>
+}
+//]
+#endif
+
+
+//[getting_started_exports_cpp_variable
+namespace your_project_namespace {
+ API std::string cpp_variable_name;
+}
+//]
+
+
+
+//[getting_started_exports_alias
+namespace some_namespace {
+ std::string i_am_function_with_ugly_name(const std::string& param) noexcept;
+}
+
+// When you have no control over function sources or wish to specify another name.
+BOOST_DLL_ALIAS(some_namespace::i_am_function_with_ugly_name, pretty_name)
+//]
+
+//[getting_started_exports_c_function
+API int c_func_name(int);
+//]
+
+//[getting_started_exports_c_variable
+API int c_variable_name;
+//]
+
+int c_func_name(int i) { return ++i; }
+int c_variable_name = 1;
+std::string your_project_namespace::cpp_variable_name = "some value";
+
+namespace some_namespace {
+ std::string i_am_function_with_ugly_name(const std::string& param) noexcept {
+ return param + " Hello from lib!";
+ }
+
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+ int i_am_a_cpp11_function(std::string&& param) noexcept {
+ return static_cast<int>(param.size());
+ }
+#endif
+}
+
diff --git a/src/boost/libs/dll/example/mangled/import_class.cpp b/src/boost/libs/dll/example/mangled/import_class.cpp
new file mode 100644
index 000000000..eee4a9616
--- /dev/null
+++ b/src/boost/libs/dll/example/mangled/import_class.cpp
@@ -0,0 +1,47 @@
+// Copyright 2016 Klemens Morgenstern
+//
+// 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 "../b2_workarounds.hpp" // contains dll_test::replace_with_full_path
+
+//[import_class_setup
+
+#include <boost/dll/smart_library.hpp>
+#include <boost/dll/import_mangled.hpp>
+#include <boost/dll/import_class.hpp>
+
+
+
+int main(int argc, char* argv[]) {
+ /*<-*/ b2_workarounds::argv_to_path_guard guard(argc, argv); /*->*/
+ boost::dll::fs::path lib_path(argv[1]); // argv[1] contains path to directory with our plugin library
+ smart_library lib(lib_path);// smart library instance
+//]
+//[import_class_size
+ auto size_f = import_mangled<std::size_t()>("space::my_plugin::size"); //get the size function
+
+ auto size = (*size_f)(); // get the size of the class
+//]
+//[import_class_value
+ auto value = import_mangled<int>(lib, "space::my_plugin::value");
+//]
+//[import_class_ctor
+ auto cl = import_class<class alias, const std::string&>(lib, "space::my_plugin::some_class", size, "MyName");
+//]
+//[import_class_name
+ auto name = import_mangled<const alias, std::string()>(lib, "name");
+ std::cout << "Name: " << (cl->*name)() << std::endl;
+//]
+//[import_class_calc
+ auto calc = import_mangled<alias, float(float, float), int(int, int)>(lib, "calculate");
+ std::cout << "Calc(float): " (cl->*calc)(5.f, 2.f) << std::endl;
+ std::cout << "Calc(int): " (cl->*calc)(5, 2) << std::endl;
+//]
+//[import_class_typeinfo
+ std::type_info &ti = cl.get_type_info();
+//]
+}
diff --git a/src/boost/libs/dll/example/mangled/my_cpp_plugin.hpp b/src/boost/libs/dll/example/mangled/my_cpp_plugin.hpp
new file mode 100644
index 000000000..3f9e9ee16
--- /dev/null
+++ b/src/boost/libs/dll/example/mangled/my_cpp_plugin.hpp
@@ -0,0 +1,43 @@
+// Copyright 2016 Antony Polukhin.
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt
+// or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_DLL_MY_CPP_PLUGIN_API_HPP
+#define BOOST_DLL_MY_CPP_PLUGIN_API_HPP
+
+//[cppplug
+#include <string>
+
+namespace space {
+
+class BOOST_SYMBOL_EXPORT my_plugin
+{
+ std::string _name;
+public:
+ std::string name() const;
+ float calculate(float x, float y);
+ int calculate(int, x, int y);
+ static std::size_t size();
+ my_plugin(const std::string & name);
+ my_plugin();
+ ~my_plugin_api();
+ static int value;
+};
+
+}
+//]
+
+std::string space::my_plugin_api::name() const {return _name;}
+float space::my_plugin::calculate(float x, float y) {return x/y;}
+int space::my_plugin::calculate(int, x, int y) {return x/y;}
+std::size_t my_plugin::size() {return sizeof(my_plugin);}
+space::my_plugin::my_plugin(const std::string & name) : _name(name) {}
+space::my_plugin::my_plugin() : _name("Empty") {}
+space::my_plugin::~my_plugin_api() {}
+int space::my_plugin::value = 42;
+
+
+#endif // BOOST_DLL_MY_PLUGIN_API_HPP
+
diff --git a/src/boost/libs/dll/example/mangled/smart_lib.cpp b/src/boost/libs/dll/example/mangled/smart_lib.cpp
new file mode 100644
index 000000000..d8cb69c6e
--- /dev/null
+++ b/src/boost/libs/dll/example/mangled/smart_lib.cpp
@@ -0,0 +1,58 @@
+// Copyright 2016 Klemens D. Morgenstern.
+//
+// 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)
+
+#include "../b2_workarounds.hpp" // contains dll_test::replace_with_full_path
+
+//[smart_lib_setup
+#include <boost/dll/smart_library.hpp> // for import_alias
+#include <iostream>
+#include <memory>
+
+namespace dll = boost::dll;
+
+struct alias;
+
+int main(int argc, char* argv[]) {
+ /*<-*/ b2_workarounds::argv_to_path_guard guard(argc, argv); /*->*/
+ boost::dll::fs::path lib_path(argv[1]); // argv[1] contains path to directory with our plugin library
+ dll::smart_lib lib(lib_path); // smart library instance
+//]
+//[smart_lib_size
+ auto size_f = lib.get_function<std::size_t()>("space::my_plugin::size"); //get the size function
+
+ auto size = size_f(); // get the size of the class
+ std::unique_ptr<char[], size> buffer(new char[size]); //allocate a buffer for the import
+ alias & inst = *reinterpret_cast<alias*>(buffer.get()); //cast it to our alias type.
+//]
+//[smart_lib_type_alias
+ lib.add_type_alias("space::my_plugin"); //add an alias, so i can import a class that is not declared here
+//]
+//[smart_lib_ctor
+ auto ctor = lib.get_constructor<alias(const std::string&)>(); //get the constructor
+ ctor.call_standard(&inst, "MyName"); //call the non-allocating constructor. The allocating-constructor is a non-portable feature
+//]
+//[smart_lib_name
+ auto name_f = lib.get_mem_fn<const alias, std::string()>("name");//import the name function
+ std::cout << "Name Call: " << (inst.*name_f)() << std::endl;
+//]
+//[smart_lib_calculate
+ //import both calculate functions
+ auto calc_f = lib.get_mem_fn<alias, float(float, float)>("calculate");
+ auto calc_i = lib.get_mem_fn<alias, int(int, int)> ("calculate");
+
+ std::cout << "calc(float): " << (inst.*calc_f)(5., 2.) << std::endl;
+ std::cout << "calc(int) : " << (inst.*calc_f)(5, 2) << std::endl;
+//]
+//[smart_lib_var
+ auto & var = lib.get_variable<int>("space::my_plugin::value");
+ cout << "value " << var << endl;
+//]
+//[smart_lib_dtor
+ auto dtor = lib.get_destructor<alias>(); //get the destructor
+ dtor.call_standard(&inst);
+ std::cout << "plugin->calculate(1.5, 1.5) call: " << plugin->calculate(1.5, 1.5) << std::endl;
+}
+//]
diff --git a/src/boost/libs/dll/example/tutorial1/my_plugin_sum.cpp b/src/boost/libs/dll/example/tutorial1/my_plugin_sum.cpp
new file mode 100644
index 000000000..09b78a643
--- /dev/null
+++ b/src/boost/libs/dll/example/tutorial1/my_plugin_sum.cpp
@@ -0,0 +1,43 @@
+// Copyright 2014 Renato Tegon Forti, Antony Polukhin.
+// Copyright 2015-2019 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)
+
+#include <iostream>
+
+
+//[plugcpp_my_plugin_sum
+#include <boost/config.hpp> // for BOOST_SYMBOL_EXPORT
+#include "../tutorial_common/my_plugin_api.hpp"
+
+namespace my_namespace {
+
+class my_plugin_sum : public my_plugin_api {
+public:
+ my_plugin_sum() {
+ std::cout << "Constructing my_plugin_sum" << std::endl;
+ }
+
+ std::string name() const {
+ return "sum";
+ }
+
+ float calculate(float x, float y) {
+ return x + y;
+ }
+
+ ~my_plugin_sum() {
+ std::cout << "Destructing my_plugin_sum ;o)" << std::endl;
+ }
+};
+
+// Exporting `my_namespace::plugin` variable with alias name `plugin`
+// (Has the same effect as `BOOST_DLL_ALIAS(my_namespace::plugin, plugin)`)
+extern "C" BOOST_SYMBOL_EXPORT my_plugin_sum plugin;
+my_plugin_sum plugin;
+
+} // namespace my_namespace
+
+//]
diff --git a/src/boost/libs/dll/example/tutorial1/tutorial1.cpp b/src/boost/libs/dll/example/tutorial1/tutorial1.cpp
new file mode 100644
index 000000000..2827a6399
--- /dev/null
+++ b/src/boost/libs/dll/example/tutorial1/tutorial1.cpp
@@ -0,0 +1,31 @@
+// Copyright 2014 Renato Tegon Forti, Antony Polukhin.
+// Copyright 2015-2019 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)
+
+#include "../b2_workarounds.hpp" // contains dll_test::replace_with_full_path
+
+//[callplugcpp_tutorial1
+#include <boost/dll/import.hpp> // for import_alias
+#include <iostream>
+#include "../tutorial_common/my_plugin_api.hpp"
+
+namespace dll = boost::dll;
+
+int main(int argc, char* argv[]) {
+ /*<-*/ b2_workarounds::argv_to_path_guard guard(argc, argv); /*->*/
+ boost::dll::fs::path lib_path(argv[1]); // argv[1] contains path to directory with our plugin library
+ boost::shared_ptr<my_plugin_api> plugin; // variable to hold a pointer to plugin variable
+ std::cout << "Loading the plugin" << std::endl;
+
+ plugin = dll::import<my_plugin_api>( // type of imported symbol is located between `<` and `>`
+ lib_path / "my_plugin_sum", // path to the library and library name
+ "plugin", // name of the symbol to import
+ dll::load_mode::append_decorations // makes `libmy_plugin_sum.so` or `my_plugin_sum.dll` from `my_plugin_sum`
+ );
+
+ std::cout << "plugin->calculate(1.5, 1.5) call: " << plugin->calculate(1.5, 1.5) << std::endl;
+}
+//]
diff --git a/src/boost/libs/dll/example/tutorial2/my_plugin_aggregator.cpp b/src/boost/libs/dll/example/tutorial2/my_plugin_aggregator.cpp
new file mode 100644
index 000000000..4247f89b7
--- /dev/null
+++ b/src/boost/libs/dll/example/tutorial2/my_plugin_aggregator.cpp
@@ -0,0 +1,52 @@
+// Copyright 2014 Renato Tegon Forti, Antony Polukhin.
+// Copyright 2015-2019 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)
+
+#include <iostream>
+#include <boost/make_shared.hpp>
+
+// MinGW related workaround
+#define BOOST_DLL_FORCE_ALIAS_INSTANTIATION
+
+//[plugcpp_my_plugin_aggregator
+#include <boost/dll/alias.hpp> // for BOOST_DLL_ALIAS
+#include "../tutorial_common/my_plugin_api.hpp"
+
+namespace my_namespace {
+
+class my_plugin_aggregator : public my_plugin_api {
+ float aggr_;
+ my_plugin_aggregator() : aggr_(0) {}
+
+public:
+ std::string name() const {
+ return "aggregator";
+ }
+
+ float calculate(float x, float y) {
+ aggr_ += x + y;
+ return aggr_;
+ }
+
+ // Factory method
+ static boost::shared_ptr<my_plugin_aggregator> create() {
+ return boost::shared_ptr<my_plugin_aggregator>(
+ new my_plugin_aggregator()
+ );
+ }
+};
+
+
+BOOST_DLL_ALIAS(
+ my_namespace::my_plugin_aggregator::create, // <-- this function is exported with...
+ create_plugin // <-- ...this alias name
+)
+
+} // namespace my_namespace
+//]
+
+
+
diff --git a/src/boost/libs/dll/example/tutorial2/tutorial2.cpp b/src/boost/libs/dll/example/tutorial2/tutorial2.cpp
new file mode 100644
index 000000000..83addb83f
--- /dev/null
+++ b/src/boost/libs/dll/example/tutorial2/tutorial2.cpp
@@ -0,0 +1,36 @@
+// Copyright 2014 Renato Tegon Forti, Antony Polukhin.
+// Copyright 2015-2019 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)
+
+#include "../b2_workarounds.hpp"
+
+//[callplugcpp_tutorial2
+#include <boost/dll/import.hpp> // for import_alias
+#include <boost/function.hpp>
+#include <iostream>
+#include "../tutorial_common/my_plugin_api.hpp"
+
+namespace dll = boost::dll;
+
+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
+ shared_library_path, // path to library
+ "create_plugin", // symbol to import
+ dll::load_mode::append_decorations // do append extensions and prefixes
+ );
+
+ boost::shared_ptr<my_plugin_api> plugin = creator();
+ std::cout << "plugin->calculate(1.5, 1.5) call: " << plugin->calculate(1.5, 1.5) << std::endl;
+ std::cout << "plugin->calculate(1.5, 1.5) second call: " << plugin->calculate(1.5, 1.5) << std::endl;
+ std::cout << "Plugin Name: " << plugin->name() << std::endl;
+}
+//]
diff --git a/src/boost/libs/dll/example/tutorial3/tutorial3.cpp b/src/boost/libs/dll/example/tutorial3/tutorial3.cpp
new file mode 100644
index 000000000..c63615ba9
--- /dev/null
+++ b/src/boost/libs/dll/example/tutorial3/tutorial3.cpp
@@ -0,0 +1,56 @@
+// Copyright 2014 Renato Tegon Forti, Antony Polukhin.
+// Copyright 2015-2019 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)
+
+#include "../b2_workarounds.hpp"
+//[callplugcpp_tutorial3
+#include <boost/dll/import.hpp> // for import_alias
+#include <boost/make_shared.hpp>
+#include <boost/function.hpp>
+#include <iostream>
+#include "../tutorial_common/my_plugin_api.hpp"
+
+namespace dll = boost::dll;
+
+std::size_t search_for_symbols(const std::vector<boost::dll::fs::path>& plugins) {
+ std::size_t plugins_found = 0;
+
+ for (std::size_t i = 0; i < plugins.size(); ++i) {
+ std::cout << "Loading plugin: " << plugins[i] << '\n';
+ dll::shared_library lib(plugins[i], dll::load_mode::append_decorations);
+ if (!lib.has("create_plugin")) {
+ // no such symbol
+ continue;
+ }
+
+ // 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");
+
+ std::cout << "Matching plugin name: " << creator()->name() << std::endl;
+ ++ plugins_found;
+ }
+
+ return plugins_found;
+}
+
+//]
+
+int main(int argc, char* argv[]) {
+ BOOST_ASSERT(argc >= 3);
+ std::vector<boost::dll::fs::path> plugins;
+ plugins.reserve(argc - 1);
+ for (int i = 1; i < argc; ++i) {
+ if (b2_workarounds::is_shared_library(argv[i])) {
+ plugins.push_back(argv[i]);
+ }
+ }
+
+ const std::size_t res = search_for_symbols(plugins);
+ BOOST_ASSERT(res == 1);
+ (void)res;
+}
diff --git a/src/boost/libs/dll/example/tutorial4/load_self.cpp b/src/boost/libs/dll/example/tutorial4/load_self.cpp
new file mode 100644
index 000000000..176bc01d3
--- /dev/null
+++ b/src/boost/libs/dll/example/tutorial4/load_self.cpp
@@ -0,0 +1,39 @@
+// Copyright 2014 Renato Tegon Forti, Antony Polukhin.
+// Copyright 2015-2019 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)
+
+// MinGW related workaround
+#define BOOST_DLL_FORCE_ALIAS_INSTANTIATION
+
+//[plugcpp_my_plugin_load_self
+#include <boost/dll/shared_library.hpp> // for shared_library
+#include <boost/dll/runtime_symbol_info.hpp> // for program_location()
+#include "static_plugin.hpp" // without this headers some compilers may optimize out the `create_plugin` symbol
+#include <boost/function.hpp>
+#include <iostream>
+
+namespace dll = boost::dll;
+
+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");
+
+ std::cout << "Computed Value: " << creator()->calculate(2, 2) << std::endl;
+ //<-
+ {
+ // This block is invisible for Quickbook documentation
+ float res = creator()->calculate(10, 10);
+ if (!(res > -0.0001 && res < 0.00001)) {
+ throw std::runtime_error("Failed check: res > -0.0001 && res < 0.00001");
+ }
+ }
+ //->
+}
+
+//]
diff --git a/src/boost/libs/dll/example/tutorial4/static_plugin.cpp b/src/boost/libs/dll/example/tutorial4/static_plugin.cpp
new file mode 100644
index 000000000..84a43774b
--- /dev/null
+++ b/src/boost/libs/dll/example/tutorial4/static_plugin.cpp
@@ -0,0 +1,42 @@
+// Copyright 2014 Renato Tegon Forti, Antony Polukhin.
+// Copyright 2015-2019 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)
+
+//[plugcpp_my_plugin_staic_impl
+#include "static_plugin.hpp" // this is essential, BOOST_SYMBOL_ALIAS must be seen in this file
+
+#include <boost/make_shared.hpp>
+#include <iostream>
+
+namespace my_namespace {
+
+class my_plugin_static : public my_plugin_api {
+public:
+ my_plugin_static() {
+ std::cout << "Constructing my_plugin_static" << std::endl;
+ }
+
+ std::string name() const {
+ return "static";
+ }
+
+ float calculate(float x, float y) {
+ return x - y;
+ }
+
+ ~my_plugin_static() {
+ std::cout << "Destructing my_plugin_static" << std::endl;
+ }
+};
+
+boost::shared_ptr<my_plugin_api> create_plugin() {
+ return boost::make_shared<my_plugin_static>();
+}
+
+} // namespace my_namespace
+
+//]
+
diff --git a/src/boost/libs/dll/example/tutorial4/static_plugin.hpp b/src/boost/libs/dll/example/tutorial4/static_plugin.hpp
new file mode 100644
index 000000000..baf93ac20
--- /dev/null
+++ b/src/boost/libs/dll/example/tutorial4/static_plugin.hpp
@@ -0,0 +1,22 @@
+// Copyright 2014 Renato Tegon Forti, Antony Polukhin.
+// Copyright 2015-2019 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)
+
+//[plugcpp_my_plugin_static
+#include <boost/dll/alias.hpp> // for BOOST_DLL_ALIAS
+#include <boost/shared_ptr.hpp>
+#include "../tutorial_common/my_plugin_api.hpp"
+
+namespace my_namespace {
+ boost::shared_ptr<my_plugin_api> create_plugin(); // Forward declaration
+} // namespace my_namespace
+
+BOOST_DLL_ALIAS(
+ my_namespace::create_plugin, // <-- this function is exported with...
+ create_plugin // <-- ...this alias name
+)
+//]
+
diff --git a/src/boost/libs/dll/example/tutorial5/load_all.cpp b/src/boost/libs/dll/example/tutorial5/load_all.cpp
new file mode 100644
index 000000000..7e7b30576
--- /dev/null
+++ b/src/boost/libs/dll/example/tutorial5/load_all.cpp
@@ -0,0 +1,146 @@
+// Copyright 2014 Renato Tegon Forti, Antony Polukhin.
+// Copyright 2015-2019 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)
+
+// MinGW related workaround
+#define BOOST_DLL_FORCE_ALIAS_INSTANTIATION
+
+#include "../b2_workarounds.hpp"
+#include "../tutorial4/static_plugin.hpp"
+#include <boost/dll/runtime_symbol_info.hpp> // for program_location()
+#include <boost/dll/shared_library.hpp>
+#include <boost/make_shared.hpp>
+#include <boost/container/map.hpp>
+#include <boost/filesystem.hpp>
+#include <iostream>
+
+//[plugcpp_plugins_collector_def
+namespace dll = boost::dll;
+
+class plugins_collector {
+ // Name => plugin
+ typedef boost::container::map<std::string, dll::shared_library> plugins_t;
+
+ boost::dll::fs::path plugins_directory_;
+ plugins_t plugins_;
+
+ // loads all plugins in plugins_directory_
+ void load_all();
+
+ // 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);
+
+public:
+ plugins_collector(const boost::dll::fs::path& plugins_directory)
+ : plugins_directory_(plugins_directory)
+ {
+ load_all();
+ }
+
+ void print_plugins() const;
+
+ std::size_t count() const;
+ // ...
+};
+//]
+
+
+//[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();
+
+ // Searching a folder for files with '.so' or '.dll' extension
+ fs::recursive_directory_iterator endit;
+ for (fs::recursive_directory_iterator it(plugins_directory_); it != endit; ++it) {
+ if (!fs::is_regular_file(*it)) {
+ continue;
+ }
+ /*<-*/
+ if ( !b2_workarounds::is_shared_library((*it).path()) ) {
+ continue;
+ }
+ /*->*/
+ // We found a file. Trying to load it
+ boost::dll::fs::error_code error;
+ dll::shared_library plugin(it->path(), error);
+ if (error) {
+ continue;
+ }
+ std::cout << "Loaded (" << plugin.native() << "):" << it->path() << '\n';
+
+ // Gets plugin using "create_plugin" or "plugin" function
+ insert_plugin(boost::move(plugin));
+ }
+
+ dll::shared_library plugin(dll::program_location());
+ std::cout << "Loaded self\n";
+ insert_plugin(boost::move(plugin));
+}
+//]
+
+//[plugcpp_plugins_collector_insert_plugin
+void plugins_collector::insert_plugin(BOOST_RV_REF(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();
+ } else if (lib.has("plugin")) {
+ plugin_name = lib.get<my_plugin_api>("plugin").name();
+ } else {
+ return;
+ }
+
+ if (plugins_.find(plugin_name) == plugins_.cend()) {
+ plugins_[plugin_name] = boost::move(lib);
+ }
+}
+//]
+
+void plugins_collector::print_plugins() const {
+ plugins_t::const_iterator const end = plugins_.cend();
+ for (plugins_t::const_iterator it = plugins_.cbegin(); it != end; ++it) {
+ std::cout << '(' << it->second.native() << "): " << it->first << '\n';
+ }
+}
+
+std::size_t plugins_collector::count() const {
+ return plugins_.size();
+}
+
+
+//[plugcpp_load_all
+int main(int argc, char* argv[]) {
+ /*<-*/
+ BOOST_ASSERT(argc >= 3);
+ boost::dll::fs::path path1(argv[1]);
+ for (int i = 2; i < argc; ++i) {
+ boost::dll::fs::path path2(argv[i]);
+ boost::dll::fs::path res;
+ for (boost::dll::fs::path::iterator it1 = path1.begin(), it2 = path2.begin();
+ it1 != path1.end() && it2 != path2.end() && *it1 == *it2;
+ ++it1, ++it2)
+ {
+ res /= *it1;
+ }
+
+ path1 = res;
+ }
+
+ std::string new_argv = path1.string();
+ std::cout << "\nPlugins path: " << new_argv << ":\n";
+ argv[1] = &new_argv[0];
+ /*->*/
+ plugins_collector plugins(argv[1]);
+
+ std::cout << "\n\nUnique plugins " << plugins.count() << ":\n";
+ plugins.print_plugins();
+ // ...
+//]
+ BOOST_ASSERT(plugins.count() >= 3);
+}
+
diff --git a/src/boost/libs/dll/example/tutorial6/on_unload_lib.cpp b/src/boost/libs/dll/example/tutorial6/on_unload_lib.cpp
new file mode 100644
index 000000000..f09ede95e
--- /dev/null
+++ b/src/boost/libs/dll/example/tutorial6/on_unload_lib.cpp
@@ -0,0 +1,48 @@
+// Copyright 2014 Renato Tegon Forti, Antony Polukhin.
+// Copyright 2015-2019 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)
+
+// MinGW related workaround
+#define BOOST_DLL_FORCE_ALIAS_INSTANTIATION
+
+//[plugcpp_on_unload
+#include <boost/dll/alias.hpp> // for BOOST_DLL_ALIAS
+#include <boost/function.hpp>
+#include <vector>
+
+namespace my_namespace {
+
+struct on_unload {
+ typedef boost::function<void()> callback_t;
+ typedef on_unload this_type;
+
+ ~on_unload() {
+ for (std::size_t i = 0; i < callbacks_.size(); ++i) {
+ callback_t& function = callbacks_[i];
+ function(); // calling the callback
+ }
+ }
+
+ // not thread safe
+ static void add(const callback_t& function) {
+ static this_type instance;
+ instance.callbacks_.push_back(function);
+ }
+
+private:
+ std::vector<callback_t> callbacks_;
+ on_unload() {} // prohibit construction outside of the `add` function
+};
+
+// Exporting the static "add" function with name "on_unload"
+BOOST_DLL_ALIAS(my_namespace::on_unload::add, on_unload)
+
+} // namespace my_namespace
+
+//]
+
+
+
diff --git a/src/boost/libs/dll/example/tutorial6/tutorial6.cpp b/src/boost/libs/dll/example/tutorial6/tutorial6.cpp
new file mode 100644
index 000000000..87003f022
--- /dev/null
+++ b/src/boost/libs/dll/example/tutorial6/tutorial6.cpp
@@ -0,0 +1,39 @@
+// Copyright 2014 Renato Tegon Forti, Antony Polukhin.
+// Copyright 2015-2019 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)
+
+#include "../b2_workarounds.hpp"
+
+//[callplugcpp_tutorial6
+#include <boost/dll/import.hpp>
+#include <boost/function.hpp>
+#include <iostream>
+
+typedef boost::function<void()> callback_t;
+
+void print_unloaded() {
+ std::cout << "unloaded" << std::endl;
+}
+
+int main(int argc, char* argv[]) {
+ // argv[1] contains full path to our plugin library
+ 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"
+ );
+
+ 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();
+ std::cout << "After library unload." << std::endl;
+}
+//]
+
diff --git a/src/boost/libs/dll/example/tutorial7/library1.cpp b/src/boost/libs/dll/example/tutorial7/library1.cpp
new file mode 100644
index 000000000..fa48a5daf
--- /dev/null
+++ b/src/boost/libs/dll/example/tutorial7/library1.cpp
@@ -0,0 +1,21 @@
+// Copyright 2014 Renato Tegon Forti, Antony Polukhin.
+// Copyright 2015-2019 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)
+
+// MinGW related workaround
+#define BOOST_DLL_FORCE_ALIAS_INSTANTIATION
+
+//[plugcpp_tutorial7_library1
+#include <boost/dll/alias.hpp> // for BOOST_DLL_ALIAS_SECTIONED
+#include <iostream>
+#include <string>
+
+void print(const std::string& s) {
+ std::cout << "Hello, " << s << '!' << std::endl;
+}
+
+BOOST_DLL_ALIAS_SECTIONED(print, print_hello, Anna)
+//]
diff --git a/src/boost/libs/dll/example/tutorial7/library2.cpp b/src/boost/libs/dll/example/tutorial7/library2.cpp
new file mode 100644
index 000000000..abdd60ff2
--- /dev/null
+++ b/src/boost/libs/dll/example/tutorial7/library2.cpp
@@ -0,0 +1,26 @@
+// Copyright 2014 Renato Tegon Forti, Antony Polukhin.
+// Copyright 2015-2019 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)
+
+// MinGW related workaround
+#define BOOST_DLL_FORCE_ALIAS_INSTANTIATION
+
+//[plugcpp_tutorial7_library2
+#include <boost/dll/alias.hpp> // for BOOST_DLL_ALIAS_SECTIONED
+#include <string>
+#include <iostream>
+
+void print_howdy(const std::string& s) {
+ std::cout << "How're you doing, " << s << '?' << std::endl;
+}
+
+void print_bored(const std::string& s) {
+ std::cout << "Are you bored, " << s << '?' << std::endl;
+}
+
+BOOST_DLL_ALIAS_SECTIONED(print_howdy, howdy, Anna)
+BOOST_DLL_ALIAS_SECTIONED(print_bored, are_you_bored, Anna)
+//]
diff --git a/src/boost/libs/dll/example/tutorial7/tutorial7.cpp b/src/boost/libs/dll/example/tutorial7/tutorial7.cpp
new file mode 100644
index 000000000..e0186db27
--- /dev/null
+++ b/src/boost/libs/dll/example/tutorial7/tutorial7.cpp
@@ -0,0 +1,48 @@
+// Copyright 2014 Renato Tegon Forti, Antony Polukhin.
+// Copyright 2015-2019 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)
+
+#include <vector>
+#include "../b2_workarounds.hpp"
+
+//[callplugcpp_tutorial7
+#include <boost/dll/shared_library.hpp>
+#include <boost/dll/library_info.hpp>
+#include <iostream>
+
+void load_and_execute(const boost::dll::fs::path libraries[], std::size_t libs_count) {
+ const std::string username = "User";
+
+ for (std::size_t i = 0; i < libs_count; ++i) {
+ // Class `library_info` can extract information from a library
+ boost::dll::library_info inf(libraries[i]);
+
+ // Getting symbols exported from 'Anna' section
+ std::vector<std::string> exports = inf.symbols("Anna");
+
+ // Loading library and importing symbols from it
+ boost::dll::shared_library lib(libraries[i]);
+ for (std::size_t j = 0; j < exports.size(); ++j) {
+ std::cout << "\nFunction '" << exports[j] << "' prints:\n\t";
+ lib.get_alias<void(const std::string&)>(exports[j]) // importing function
+ (username); // calling function
+ }
+ }
+}
+//]
+
+int main(int argc, char* argv[]) {
+ /*<-*/ BOOST_ASSERT(argc >= 3); /*->*/
+ std::vector<boost::dll::fs::path> libraries;
+ libraries.reserve(argc - 1);
+ for (int i = 1; i < argc; ++i) {
+ if (b2_workarounds::is_shared_library(argv[i])) {
+ libraries.push_back(argv[i]);
+ }
+ }
+
+ load_and_execute(&libraries[0], libraries.size());
+}
diff --git a/src/boost/libs/dll/example/tutorial8/refcounting_api.hpp b/src/boost/libs/dll/example/tutorial8/refcounting_api.hpp
new file mode 100644
index 000000000..c9178110d
--- /dev/null
+++ b/src/boost/libs/dll/example/tutorial8/refcounting_api.hpp
@@ -0,0 +1,77 @@
+// Copyright 2014 Renato Tegon Forti, Antony Polukhin.
+// Copyright 2015-2019 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)
+
+//[plugcpp_my_plugin_refcounting_api
+#include "../tutorial_common/my_plugin_api.hpp"
+#include <boost/dll/config.hpp>
+
+class my_refcounting_api: public my_plugin_api {
+public:
+ // Returns path to shared object that holds a plugin.
+ // Must be instantiated in plugin.
+ virtual boost::dll::fs::path location() const = 0;
+};
+//]
+
+
+//[plugcpp_library_holding_deleter_api_bind
+#include <boost/shared_ptr.hpp>
+#include <boost/make_shared.hpp>
+#include <boost/dll/shared_library.hpp>
+
+struct library_holding_deleter {
+ boost::shared_ptr<boost::dll::shared_library> lib_;
+
+ void operator()(my_refcounting_api* p) const {
+ delete p;
+ }
+};
+
+inline boost::shared_ptr<my_refcounting_api> bind(my_refcounting_api* plugin) {
+ // getting location of the shared library that holds the plugin
+ boost::dll::fs::path location = plugin->location();
+
+ // `make_shared` is an efficient way to create a shared pointer
+ boost::shared_ptr<boost::dll::shared_library> lib
+ = boost::make_shared<boost::dll::shared_library>(location);
+
+ library_holding_deleter deleter;
+ deleter.lib_ = lib;
+
+ return boost::shared_ptr<my_refcounting_api>(
+ plugin, deleter
+ );
+}
+//]
+
+//[plugcpp_get_plugin_refcounting
+#include <boost/dll/import.hpp>
+#include <boost/function.hpp>
+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>(
+ path,
+ func_name,
+ boost::dll::load_mode::append_decorations // will be ignored for executable
+ );
+
+ // `plugin` does not hold a reference to shared library. If `creator` will go out of scope,
+ // then `plugin` can not be used.
+ my_refcounting_api* plugin = creator();
+
+ // Returned variable holds a reference to
+ // shared_library and it is safe to use it.
+ return bind( plugin );
+
+ // `creator` goes out of scope here and will be destroyed.
+}
+
+//]
+
+
diff --git a/src/boost/libs/dll/example/tutorial8/refcounting_plugin.cpp b/src/boost/libs/dll/example/tutorial8/refcounting_plugin.cpp
new file mode 100644
index 000000000..bb52cdfa8
--- /dev/null
+++ b/src/boost/libs/dll/example/tutorial8/refcounting_plugin.cpp
@@ -0,0 +1,47 @@
+// Copyright 2014 Renato Tegon Forti, Antony Polukhin.
+// Copyright 2015-2019 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)
+
+// MinGW related workaround
+#define BOOST_DLL_FORCE_ALIAS_INSTANTIATION
+
+//[plugcpp_my_plugin_refcounting
+#include "refcounting_plugin.hpp"
+#include <boost/dll/runtime_symbol_info.hpp> // for this_line_location()
+
+namespace my_namespace {
+
+class my_plugin_refcounting : public my_refcounting_api {
+public:
+ // Must be instantiated in plugin
+ boost::dll::fs::path location() const {
+ return boost::dll::this_line_location(); // location of this plugin
+ }
+
+ std::string name() const {
+ return "refcounting";
+ }
+
+ // ...
+ //<-
+ // This block is invisible for Quickbook documentation
+ float calculate(float /*x*/, float /*y*/) {
+ return 0;
+ }
+ //->
+};
+
+} // namespace my_namespace
+
+// Factory method. Returns *simple pointer*!
+my_refcounting_api* create() {
+ return new my_namespace::my_plugin_refcounting();
+}
+
+//]
+
+
+
diff --git a/src/boost/libs/dll/example/tutorial8/refcounting_plugin.hpp b/src/boost/libs/dll/example/tutorial8/refcounting_plugin.hpp
new file mode 100644
index 000000000..990bd2141
--- /dev/null
+++ b/src/boost/libs/dll/example/tutorial8/refcounting_plugin.hpp
@@ -0,0 +1,17 @@
+// Copyright 2014 Renato Tegon Forti, Antony Polukhin.
+// Copyright 2015-2019 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)
+
+//[plugcpp_my_plugin_refcounting_hpp
+#include "refcounting_api.hpp"
+#include <boost/dll/alias.hpp> // for BOOST_DLL_ALIAS
+
+my_refcounting_api* create(); // defined in plugin
+BOOST_DLL_ALIAS(create, create_refc_plugin)
+//]
+
+
+
diff --git a/src/boost/libs/dll/example/tutorial8/tutorial8.cpp b/src/boost/libs/dll/example/tutorial8/tutorial8.cpp
new file mode 100644
index 000000000..ef169a990
--- /dev/null
+++ b/src/boost/libs/dll/example/tutorial8/tutorial8.cpp
@@ -0,0 +1,25 @@
+// Copyright 2014 Renato Tegon Forti, Antony Polukhin.
+// Copyright 2015-2019 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)
+
+#include "../b2_workarounds.hpp"
+
+//[callplugcpp_tutorial8
+#include <iostream>
+#include "refcounting_api.hpp"
+
+int main(int argc, char* argv[]) {
+ /*<-*/ b2_workarounds::argv_to_path_guard guard(argc, argv); /*->*/
+ boost::shared_ptr<my_refcounting_api> plugin = get_plugin(
+ boost::dll::fs::path(argv[1]) / "refcounting_plugin",
+ "create_refc_plugin"
+ );
+
+ std::cout << "Plugin name: " << plugin->name()
+ << ", \nlocation: " << plugin->location()
+ << std::endl;
+}
+//]
diff --git a/src/boost/libs/dll/example/tutorial8/tutorial8_static.cpp b/src/boost/libs/dll/example/tutorial8/tutorial8_static.cpp
new file mode 100644
index 000000000..810d322f5
--- /dev/null
+++ b/src/boost/libs/dll/example/tutorial8/tutorial8_static.cpp
@@ -0,0 +1,23 @@
+// Copyright 2014 Renato Tegon Forti, Antony Polukhin.
+// Copyright 2015-2019 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)
+
+//[callplugcpp_tutorial8_static
+#include <boost/dll/runtime_symbol_info.hpp> // program_location()
+#include <iostream>
+#include "refcounting_plugin.hpp"
+
+int main() {
+ boost::shared_ptr<my_refcounting_api> plugin = get_plugin(
+ boost::dll::program_location(),
+ "create_refc_plugin"
+ );
+
+ std::cout << "Plugin name: " << plugin->name()
+ << ", \nlocation: " << plugin->location()
+ << std::endl;
+}
+//]
diff --git a/src/boost/libs/dll/example/tutorial9/tutorial9.cpp b/src/boost/libs/dll/example/tutorial9/tutorial9.cpp
new file mode 100644
index 000000000..2f4f5efab
--- /dev/null
+++ b/src/boost/libs/dll/example/tutorial9/tutorial9.cpp
@@ -0,0 +1,60 @@
+// Copyright 2015-2019 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)
+
+#include <boost/predef/os.h>
+#if BOOST_OS_WINDOWS
+
+//[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 <iostream>
+#include <windows.h>
+
+namespace dll = boost::dll;
+
+int main() {
+ typedef HANDLE(__stdcall GetStdHandle_t)(DWORD ); // function signature with calling convention
+
+ // OPTION #0, requires C++11 compatible compiler that understands GetStdHandle_t signature.
+/*<-*/
+#if defined(_MSC_VER) && !defined(BOOST_NO_CXX11_TRAILING_RESULT_TYPES) && !defined(BOOST_NO_CXX11_DECLTYPE) && !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) /*->*/
+ auto get_std_handle = dll::import<GetStdHandle_t>(
+ "Kernel32.dll",
+ "GetStdHandle",
+ boost::dll::load_mode::search_system_folders
+ );
+ 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
+ // 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::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.
+ dll::shared_library lib("Kernel32.dll", dll::load_mode::search_system_folders);
+ GetStdHandle_t& func = lib.get<GetStdHandle_t>("GetStdHandle");
+
+ // Here `func` does not keep a reference to `lib`, you'll have to deal with that on your own.
+ std::cout << "1.0 GetStdHandle() returned " << func(STD_OUTPUT_HANDLE) << std::endl;
+
+ return 0;
+}
+
+//]
+
+#else // BOOST_WINDOWS
+
+#include <boost/dll/shared_library.hpp> // for dll::shared_library
+
+int main() {
+ return 0;
+}
+
+#endif // BOOST_WINDOWS
diff --git a/src/boost/libs/dll/example/tutorial_common/my_plugin_api.hpp b/src/boost/libs/dll/example/tutorial_common/my_plugin_api.hpp
new file mode 100644
index 000000000..d8fe85825
--- /dev/null
+++ b/src/boost/libs/dll/example/tutorial_common/my_plugin_api.hpp
@@ -0,0 +1,24 @@
+// Copyright 2016-2019 Antony Polukhin.
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt
+// or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_DLL_MY_PLUGIN_API_HPP
+#define BOOST_DLL_MY_PLUGIN_API_HPP
+
+//[plugapi
+#include <boost/config.hpp>
+#include <string>
+
+class BOOST_SYMBOL_VISIBLE my_plugin_api {
+public:
+ virtual std::string name() const = 0;
+ virtual float calculate(float x, float y) = 0;
+
+ virtual ~my_plugin_api() {}
+};
+//]
+
+#endif // BOOST_DLL_MY_PLUGIN_API_HPP
+
diff --git a/src/boost/libs/dll/index.html b/src/boost/libs/dll/index.html
new file mode 100644
index 000000000..508869790
--- /dev/null
+++ b/src/boost/libs/dll/index.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<!--
+ Copyright (c) 2014-2015 Antony Polukhin
+ antoshkka at gmail dot com
+
+ Distributed under the Boost Software License,
+ Version 1.0. (See accompanying file LICENSE_1_0.txt
+ or copy at http://boost.org/LICENSE_1_0.txt)
+-->
+<html>
+<head>
+<meta charset="utf-8">
+<meta http-equiv="refresh" content="0; url=../../doc/html/boost_dll.html">
+<title>Boost.TypeIndex</title>
+<style>
+ body {
+ background: #fff;
+ color: #000;
+ }
+ a {
+ color: #00f;
+ text-decoration: none;
+ }
+</style>
+</head>
+<body>
+ <p>
+ Automatic redirection failed, please go to
+ <a href="../../doc/html/boost_dll.html">../../doc/html/boost_dll.html</a>
+ </p>
+ <p>
+ &copy; 2014-2015 Antony Polukhin
+ </p>
+</body>
+</html>
diff --git a/src/boost/libs/dll/meta/libraries.json b/src/boost/libs/dll/meta/libraries.json
new file mode 100644
index 000000000..ebe057308
--- /dev/null
+++ b/src/boost/libs/dll/meta/libraries.json
@@ -0,0 +1,15 @@
+{
+ "key": "dll",
+ "name": "DLL",
+ "authors": [
+ "Antony Polukhin", "Renato Tegon Forti"
+ ],
+ "maintainers": [
+ "Antony Polukhin <antoshkka -at- gmail.com>"
+ ],
+ "description": "Library for comfortable work with DLL and DSO.",
+ "std": [ "proposal" ],
+ "category": [
+ "System"
+ ]
+}
diff --git a/src/boost/libs/dll/test/Jamfile.v2 b/src/boost/libs/dll/test/Jamfile.v2
new file mode 100644
index 000000000..b7ea3909d
--- /dev/null
+++ b/src/boost/libs/dll/test/Jamfile.v2
@@ -0,0 +1,95 @@
+#
+# Copyright Renato Tegon Forti, Antony Polukhin 2011 - 2019.
+# 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
+
+# bring in rules for testing
+import testing ;
+import path ;
+
+local RDYNAMIC = <target-os>freebsd:<linkflags>"-rdynamic" <target-os>solaris:<linkflags>"-Bdynamic" <target-os>aix:<linkflags>"-rdynamic"
+ <target-os>qnxnto,<toolset>qcc:<linkflags>"-Bdynamic" <target-os>qnxnto,<toolset>gcc:<linkflags>"-rdynamic"
+ <target-os>android:<linkflags>"-rdynamic" <target-os>linux:<linkflags>"-rdynamic" <target-os>darwin,<toolset>gcc:<linkflags>"-dynamic"
+ <target-os>darwin,<toolset>clang:<linkflags>"-rdynamic" <target-os>iphone:<linkflags>"-rdynamic" ;
+
+
+# Static library that is not linked with any of the boost libs
+lib static_plugin : ../example/tutorial4/static_plugin.cpp : <link>static <define>BOOST_SYSTEM_NO_DEPRECATED $(RDYNAMIC) ;
+lib static_refcounting_plugin : ../example/tutorial8/refcounting_plugin.cpp : <link>static <define>BOOST_SYSTEM_NO_DEPRECATED <variant>release $(RDYNAMIC) ;
+
+
+project
+ : source-location .
+ : requirements
+
+ # linux
+ <target-os>linux:<linkflags>"-ldl"
+ <toolset>gcc:<cxxflags>"-Wall -Wextra -pedantic -Wno-long-long"
+
+ # others
+ <local-visibility>hidden
+ <library>/boost/filesystem//boost_filesystem
+ <library>/boost/system//boost_system
+ <threading>multi
+ <define>BOOST_SYSTEM_NO_DEPRECATED
+ ;
+{
+
+ # our test lib for shared library tests
+ lib test_library : test_library.cpp : <link>shared ;
+ lib getting_started_library : ../example/getting_started_library.cpp : <link>shared ;
+ lib my_plugin_sum : ../example/tutorial1/my_plugin_sum.cpp : <link>shared ;
+ lib my_plugin_aggregator : ../example/tutorial2/my_plugin_aggregator.cpp : <link>shared ;
+ lib on_unload_lib : ../example/tutorial6/on_unload_lib.cpp : <link>shared ;
+ lib library1 : ../example/tutorial7/library1.cpp : <link>shared ;
+ lib library2 : ../example/tutorial7/library2.cpp : <link>shared ;
+ lib refcounting_plugin : ../example/tutorial8/refcounting_plugin.cpp : <link>shared ;
+ lib cpp_plugin : cpp_test_library.cpp : <link>shared ;
+
+ test-suite boostdll
+ :
+ [ run link1.cpp link2.cpp : : : : validate_link ]
+ [ run shared_library_load_test.cpp : : library1 test_library : <link>shared ]
+ [ run shared_library_search_symbol_test.cpp : : test_library : $(RDYNAMIC) <link>shared ]
+ [ run shared_library_get_symbol_test.cpp : : test_library : $(RDYNAMIC) <link>shared ]
+ [ run shared_library_get_symbol_test.cpp
+ :
+ : test_library
+ : $(RDYNAMIC) <target-os>windows:<define>BOOST_USE_WINDOWS_H <link>shared
+ : get_symbol_windows_h_forced
+ ]
+ [ run symbol_runtime_info_test.cpp : : test_library : $(RDYNAMIC) <link>shared ]
+ [ run shared_library_errors.cpp : : test_library : <test-info>always_show_run_output <link>shared ]
+ [ run structures_tests.cpp ]
+ [ run library_info_test.cpp ../example/tutorial4/static_plugin.cpp : : test_library : <test-info>always_show_run_output <link>shared ]
+ [ run ../example/getting_started.cpp : : getting_started_library : <link>shared ]
+ [ run ../example/tutorial1/tutorial1.cpp : : my_plugin_sum : <link>shared ]
+ [ run ../example/tutorial2/tutorial2.cpp : : my_plugin_aggregator : <link>shared ]
+ [ run ../example/tutorial3/tutorial3.cpp : : my_plugin_aggregator my_plugin_sum : <link>shared ]
+ [ run ../example/tutorial4/load_self.cpp ../example/tutorial4/static_plugin.cpp
+ : : : <variant>release $(RDYNAMIC)
+ ]
+ [ run ../example/tutorial5/load_all.cpp ../example/tutorial4/static_plugin.cpp
+ : : getting_started_library my_plugin_aggregator my_plugin_sum : $(RDYNAMIC) <link>shared
+ ]
+ [ run ../example/tutorial6/tutorial6.cpp : : on_unload_lib : <link>shared ]
+ [ run ../example/tutorial7/tutorial7.cpp : : library1 library2 : <link>shared ]
+ [ run ../example/tutorial8/tutorial8.cpp : : refcounting_plugin : <link>shared ]
+ [ run ../example/tutorial8/tutorial8_static.cpp : : : <link>static <variant>release $(RDYNAMIC) <test-info>always_show_run_output <library>static_refcounting_plugin
+ # Known problem: unsupported __dllexport__ with weak symbols + GNU linker features (no non-weak unresolved symbols in executable => no need to link libraries)
+ <target-os>windows,<toolset>gcc:<build>no
+ ]
+ [ run ../example/tutorial9/tutorial9.cpp ]
+ # test for shared libraries
+ [ 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_load_test.cpp : : cpp_plugin ]
+ [ run cpp_import_test.cpp : : cpp_plugin ]
+ [ run template_method_linux_test.cpp : : cpp_plugin ]
+ ;
+}
diff --git a/src/boost/libs/dll/test/cpp_import_class_test.cpp b/src/boost/libs/dll/test/cpp_import_class_test.cpp
new file mode 100644
index 000000000..60e0adc0b
--- /dev/null
+++ b/src/boost/libs/dll/test/cpp_import_class_test.cpp
@@ -0,0 +1,115 @@
+// Copyright 2016 Klemens Morgenstern
+//
+// 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/predef.h>
+
+#if (__cplusplus >= 201402L) || (BOOST_COMP_MSVC >= BOOST_VERSION_NUMBER(14,0,0))
+
+#include "../example/b2_workarounds.hpp"
+
+#include <iostream>
+
+using namespace std;
+
+#include <boost/dll/smart_library.hpp>
+#include <boost/dll/import_mangled.hpp>
+#include <boost/dll/import_class.hpp>
+
+#include <boost/core/lightweight_test.hpp>
+#include <boost/filesystem.hpp>
+#include <boost/variant.hpp>
+#include <boost/function.hpp>
+
+#define L cout << __LINE__ << endl;
+
+int main(int argc, char* argv[])
+{
+ using namespace boost::dll;
+ using namespace boost::dll::experimental;
+ boost::dll::fs::path pt = b2_workarounds::first_lib_from_argv(argc, argv);
+
+ BOOST_TEST(!pt.empty());
+ std::cout << "Library: " << pt << std::endl;
+
+ smart_library sm(pt);
+
+ auto static_val = import_mangled<int>(sm, "some_space::some_class::value");
+
+ std::cout << "--------------------- Entry Points ------------------------\n" << std::endl;
+ for (auto &s : sm.symbol_storage().get_storage())
+ std::cout << s.demangled << std::endl;
+
+ std::cout << "-----------------------------------------------------------\n\n" << std::endl;
+
+
+ auto sp_variable = import_mangled<double>(sm, "some_space::variable");
+
+ auto unscoped_var = import_mangled<int>(sm, "unscoped_var");
+
+ std::size_t type_size = *import_mangled<std::size_t>(sm, "some_space::size_of_some_class");
+ {
+
+#if defined(_MSC_VER) // MSVC, Clang-cl, and ICC on Windows
+ class override_class{};
+ auto cl = import_class<override_class, int>(sm, "some_space::some_class", type_size, 42);
+#else
+ auto cl = import_class<class override_class, int>(sm, "some_space::some_class", type_size, 42);
+#endif
+ BOOST_TEST(!cl.is_copy_assignable());
+ BOOST_TEST(!cl.is_copy_constructible());
+
+ BOOST_TEST( cl.is_move_assignable());
+ BOOST_TEST( cl.is_move_constructible());
+
+ BOOST_TEST(*static_val == 42);
+
+ auto i = cl.call<const override_class, int()>("get")();
+ BOOST_TEST(i == 456);
+ cl.call<void(int)>("set")(42);
+ i = 0;
+ i = cl.call<const override_class, int()>("get")();
+ BOOST_TEST(i == 42);
+
+ auto func = import_mangled<
+ override_class, double(double, double), int(int, int),
+ volatile override_class, int(int, int),
+ const volatile override_class, double(double, double)>(sm, "func");
+
+
+
+ BOOST_TEST((cl->*func)(3.,2.) == 6.);
+ BOOST_TEST((cl->*func)(1 ,2 ) == 3 );
+
+ auto fun2 = cl.import<double(double, double), int(int, int)>("func");
+
+ BOOST_TEST((cl->*fun2)(3.,2.) == 6.);
+ BOOST_TEST((cl->*fun2)(5 ,2 ) == 7 );
+
+ //test if it binds.
+ boost::function<int(override_class* const, int, int)> mem_fn_obj = func;
+
+
+ const std::type_info & ti = cl.get_type_info();
+ std::string imp_name = boost::core::demangle(ti.name());
+#if defined(_MSC_VER) // MSVC, Clang-cl, and ICC on Windows
+ std::string exp_name = "struct some_space::some_class";
+#else
+ std::string exp_name = "some_space::some_class";
+#endif
+ BOOST_TEST(imp_name == exp_name);
+ }
+
+ BOOST_TEST(*static_val == 0);
+
+ return boost::report_errors();
+}
+
+#else
+int main() {return 0;}
+#endif
diff --git a/src/boost/libs/dll/test/cpp_import_test.cpp b/src/boost/libs/dll/test/cpp_import_test.cpp
new file mode 100644
index 000000000..b6005d058
--- /dev/null
+++ b/src/boost/libs/dll/test/cpp_import_test.cpp
@@ -0,0 +1,81 @@
+// Copyright 2016 Klemens Morgenstern
+//
+// 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/predef.h>
+
+#if (__cplusplus >= 201402L) || (BOOST_COMP_MSVC >= BOOST_VERSION_NUMBER(14,0,0))
+
+#include "../example/b2_workarounds.hpp"
+
+#include <boost/dll/smart_library.hpp>
+#include <boost/dll/import_mangled.hpp>
+
+#include <boost/core/lightweight_test.hpp>
+#include <boost/filesystem.hpp>
+#include <boost/variant.hpp>
+#include <boost/function.hpp>
+
+#include <iostream>
+
+struct override_class
+{
+ int arr[32];
+};
+
+
+int main(int argc, char* argv[])
+{
+ using namespace boost::dll;
+ using namespace boost::dll::experimental;
+ boost::dll::fs::path pt = b2_workarounds::first_lib_from_argv(argc, argv);
+
+ BOOST_TEST(!pt.empty());
+ std::cout << "Library: " << pt << std::endl;
+
+ smart_library sm(pt);
+
+ auto sp_variable = import_mangled<double>(sm, "some_space::variable");
+
+ auto unscoped_var = import_mangled<int>(sm, "unscoped_var");
+
+
+ auto ovl = import_mangled<void(int), void(double)>(sm, "overloaded");
+
+ ovl(12);
+ BOOST_TEST(*unscoped_var == 12);
+ ovl(5.0);
+ BOOST_TEST(*sp_variable == 5.0);
+
+ boost::function<void(int)> f_test = ovl;//test if it binds
+ f_test(-2);
+ BOOST_TEST(*unscoped_var == -2);
+
+ sm.add_type_alias<override_class>("some_space::some_class");
+
+ auto func = import_mangled<
+ override_class, double(double, double), int(int, int),
+ volatile override_class, int(int, int),
+ const volatile override_class, double(double, double)>(sm, "func");
+
+ override_class override_class_varible{};
+
+ override_class *ov = &override_class_varible;
+ volatile override_class *ovv = ov;
+ const volatile override_class *ovcv = ov;
+
+ BOOST_TEST(func(ov, 3.,2.) == 6.);
+ BOOST_TEST(func(ov, 1,2 ) == 3 );
+ BOOST_TEST(func(ovv, 10,2) == 8 );
+ BOOST_TEST(func(ovcv, 9,2) == 4.5 );
+
+ return boost::report_errors();
+}
+
+#else
+int main() {return 0;}
+#endif
diff --git a/src/boost/libs/dll/test/cpp_load_test.cpp b/src/boost/libs/dll/test/cpp_load_test.cpp
new file mode 100644
index 000000000..a95a9afdc
--- /dev/null
+++ b/src/boost/libs/dll/test/cpp_load_test.cpp
@@ -0,0 +1,228 @@
+// Copyright 2016 Klemens Morgenstern
+//
+// 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/predef.h>
+
+#if (__cplusplus >= 201402L) || (BOOST_COMP_MSVC >= BOOST_VERSION_NUMBER(14,0,0))
+
+#include "../example/b2_workarounds.hpp"
+
+#include <boost/dll/smart_library.hpp>
+#include <boost/core/lightweight_test.hpp>
+#include <boost/filesystem.hpp>
+#include <boost/variant.hpp>
+
+#include <iostream>
+
+struct override_class
+{
+ int arr[32];
+};
+
+
+int main(int argc, char* argv[])
+{
+ using namespace boost::dll;
+ using namespace boost::dll::experimental;
+ boost::dll::fs::path pt = b2_workarounds::first_lib_from_argv(argc, argv);
+
+ BOOST_TEST(!pt.empty());
+ std::cout << "Library: " << pt << std::endl;
+ std::cerr << 1 << ' ';
+ smart_library sm(pt);
+
+ auto& unscoped_var = sm.get_variable<int>("unscoped_var");
+ BOOST_TEST(unscoped_var == 42);
+ std::cerr << 2 << ' ';
+ auto& unscoped_c_var = sm.get_variable<const double>("unscoped_c_var");
+ BOOST_TEST(unscoped_c_var == 1.234);
+
+ std::cerr << 3 << ' ';
+ auto& sp_variable = sm.get_variable<double>("some_space::variable");
+ BOOST_TEST(sp_variable == 0.2);
+
+ std::cerr << 4 << ' ';
+ auto scoped_fun = sm.get_function<const int&()>("some_space::scoped_fun");
+ BOOST_TEST(scoped_fun != nullptr);
+ { std::cerr << 5 << ' ';
+ auto &res = scoped_fun();
+ const int expected = 0xDEADBEEF;
+ BOOST_TEST(res == expected);
+ }
+ std::cerr << 6 << ' ';
+ auto ovl1 = sm.get_function<void(int)> ("overloaded");
+ auto ovl2 = sm.get_function<void(double)>("overloaded");
+ std::cerr << 7 << ' ';
+ BOOST_TEST(ovl1 != nullptr);
+ BOOST_TEST(ovl2 != nullptr);
+ BOOST_TEST(reinterpret_cast<void*>(ovl1) != reinterpret_cast<void*>(ovl2));
+ std::cerr << 8 << ' ';
+ ovl1(12);
+ BOOST_TEST(unscoped_var == 12);
+ ovl2(5.0);
+ BOOST_TEST(sp_variable == 5.0);
+ std::cerr << 9 << ' ';
+
+
+// TODO: ms.get_name on Clang has space after comma `boost::variant<double, int>`
+#if !(defined(BOOST_TRAVISCI_BUILD) && defined(_MSC_VER) && defined(BOOST_CLANG))
+ auto var1 = sm.get_function<void(boost::variant<int, double> &)>("use_variant");
+ auto var2 = sm.get_function<void(boost::variant<double, int> &)>("use_variant");
+ std::cerr << 10 << ' ';
+ BOOST_TEST(var1 != nullptr);
+ BOOST_TEST(var2 != nullptr);
+ BOOST_TEST(reinterpret_cast<void*>(var1) != reinterpret_cast<void*>(var2));
+
+ {
+ boost::variant<int, double> v1 = 232.22;
+ boost::variant<double, int> v2 = -1;
+ std::cerr << 11 << ' ';
+ var1(v1);
+ var2(v2);
+
+ struct : boost::static_visitor<void>
+ {
+ void operator()(double) {BOOST_TEST(false);}
+ void operator()(int i) {BOOST_TEST(i == 42);}
+ } vis1;
+
+ struct : boost::static_visitor<void>
+ {
+ void operator()(double d) {BOOST_TEST(d == 3.124);}
+ void operator()(int ) {BOOST_TEST(false);}
+ } vis2;
+
+ boost::apply_visitor(vis1, v1);
+ boost::apply_visitor(vis2, v2);
+
+ }
+#endif
+ std::cerr << 12 << ' ';
+ /* now test the class stuff */
+
+ //first we import and test the global variables
+
+ auto& father_val = sm.get_variable<int>("some_space::father_value");
+ auto& static_val = sm.get_variable<int>("some_space::some_class::value");
+ BOOST_TEST(father_val == 12);
+ BOOST_TEST(static_val == -1);
+ std::cerr << 13 << ' ';
+ //now get the static function.
+ auto set_value = sm.get_function<void(const int &)>("some_space::some_class::set_value");
+ BOOST_TEST(set_value != nullptr);
+ std::cerr << 14 << ' ';
+ set_value(42);
+ BOOST_TEST(static_val == 42); //alright, static method works.
+
+
+ //alright, now import the class members
+ //first add the type alias.
+ sm.add_type_alias<override_class>("some_space::some_class");
+ std::cerr << 15 << ' ';
+ auto set = sm.get_mem_fn<override_class, void(int)>("set");
+
+ std::cerr << 16 << ' ';
+ try {
+ sm.get_mem_fn<override_class, int()>("get");
+ BOOST_TEST(false);
+ } catch(boost::dll::fs::system_error &) {}
+ auto get = sm.get_mem_fn<const override_class, int()>("get");
+ std::cerr << 17 << ' ';
+ BOOST_TEST(get != nullptr);
+ BOOST_TEST(set != nullptr);
+ std::cerr << 18 << ' ';
+ auto func_dd = sm.get_mem_fn<override_class, double(double, double)>("func");
+ auto func_ii = sm.get_mem_fn<override_class, int(int, int)> ("func");
+ auto func_iiv = sm.get_mem_fn<volatile override_class, int(int, int)> ("func");
+ auto func_ddc = sm.get_mem_fn<const volatile override_class, double(double, double)>("func");
+
+ std::cerr << 19 << ' ';
+ BOOST_TEST(func_dd != nullptr);
+ BOOST_TEST(func_ii != nullptr);
+
+ std::cerr << 20 << ' ';
+ auto ctor_v = sm.get_constructor<override_class()>();
+ auto ctor_i = sm.get_constructor<override_class(int)>();
+
+ auto dtor = sm.get_destructor<override_class>();
+ std::cerr << 21 << ' ';
+ //actually never used.
+ if (ctor_v.has_allocating())
+ {
+ //allocate
+ auto p = ctor_v.call_allocating();
+
+ //assert it works
+ auto val = (p->*get)();
+ BOOST_TEST(val == 123);
+ //deallocate
+ dtor.call_deleting(p);
+ //now i cannot assert that it deletes, since it would crash.
+ }
+ //More tests to assure the correct this-ptr
+ std::cerr << 22 << ' ';
+ typedef override_class * override_class_p;
+ override_class_p &this_dll = sm.shared_lib().get<override_class_p>("this_");
+
+ std::cerr << 23 << ' ';
+ //ok, now load the ctor/dtor
+ override_class oc;
+
+ override_class_p this_exe = &oc;
+
+ for (auto& i : oc.arr) {
+ i = 0;
+ }
+ std::cerr << 24 << ' ';
+
+ BOOST_TEST((oc.*get)() == 0); BOOST_TEST(this_dll == this_exe);
+
+ ctor_i.call_standard(&oc, 12); BOOST_TEST(this_dll == this_exe);
+
+ BOOST_TEST(static_val == 12);
+ BOOST_TEST((oc.*get)() == 456); BOOST_TEST(this_dll == this_exe);
+ (oc.*set)(42);
+ BOOST_TEST((oc.*get)() == 42); BOOST_TEST(this_dll == this_exe);
+ std::cerr << 25 << ' ';
+
+ BOOST_TEST((oc.*func_dd)(3,2) == 6); BOOST_TEST(this_dll == this_exe);
+ BOOST_TEST((oc.*func_ii)(1,2) == 3); BOOST_TEST(this_dll == this_exe);
+ BOOST_TEST((oc.*func_ddc)(10,2) == 5); BOOST_TEST(this_dll == this_exe);
+ BOOST_TEST((oc.*func_iiv)(9,2) == 7); BOOST_TEST(this_dll == this_exe);
+ std::cerr << 26 << ' ';
+ dtor.call_standard(&oc); BOOST_TEST(this_dll == this_exe);
+ BOOST_TEST(static_val == 0);
+
+#ifndef BOOST_NO_RTTI
+ const auto& ti = sm.get_type_info<override_class>();
+ BOOST_TEST(ti.name() != nullptr);
+#endif
+ std::cerr << 27 << ' ';
+ //test the ovls helper.
+ {
+ namespace ex = boost::dll::experimental;
+ auto &var = ex::get<double>(sm, "some_space::variable");
+ BOOST_TEST(&var == &sp_variable);
+
+ auto fun = ex::get<void(int)>(sm, "overloaded");
+ BOOST_TEST(fun == ovl1);
+
+ auto func_ii = sm.get_mem_fn<override_class, int(int, int)> ("func");
+
+ auto mem_fn = ex::get<override_class, int(int, int)>(sm, "func");
+
+ BOOST_TEST(mem_fn == func_ii);
+ }
+
+ std::cerr << 28 << ' ';
+ return boost::report_errors();
+}
+
+#else
+int main() {return 0;}
+#endif
diff --git a/src/boost/libs/dll/test/cpp_mangle_test.cpp b/src/boost/libs/dll/test/cpp_mangle_test.cpp
new file mode 100644
index 000000000..1b235877b
--- /dev/null
+++ b/src/boost/libs/dll/test/cpp_mangle_test.cpp
@@ -0,0 +1,133 @@
+// Copyright 2016 Klemens Morgenstern
+//
+// 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/predef.h>
+
+#if (__cplusplus >= 201402L) || (BOOST_COMP_MSVC >= BOOST_VERSION_NUMBER(14,0,0))
+
+#include "../example/b2_workarounds.hpp"
+
+#include <boost/dll/smart_library.hpp>
+#include <boost/core/lightweight_test.hpp>
+#include <boost/filesystem.hpp>
+#include <boost/variant.hpp>
+
+#include <iostream>
+
+
+struct override_class {};
+
+
+int main(int argc, char* argv[])
+{
+ using namespace boost::dll;
+ using mangled_storage = detail::mangled_storage_impl;
+
+ boost::dll::fs::path pt = b2_workarounds::first_lib_from_argv(argc, argv);
+
+ std::cout << "Library: " << pt << std::endl;
+ library_info lib{pt};
+
+ mangled_storage ms(lib);
+
+ std::cout << "Symbols: " << std::endl;
+
+ for (auto &s : ms.get_storage())
+ {
+ std::cout << s.demangled << std::endl;
+ }
+
+ std::string v;
+ v = ms.get_variable<double>("some_space::variable");
+
+ BOOST_TEST(!v.empty()); //check if a symbols was found.
+ BOOST_TEST(v != "some_space::variable"); //demangle is different
+
+ v = ms.get_variable<double>("some_space::variable_typo");
+ BOOST_TEST(v.empty());
+
+
+ v = ms.get_variable<const double>("unscoped_c_var");
+
+ BOOST_TEST(!v.empty()); //check if a symbols was found.
+
+ v = ms.get_variable<int>("unscoped_var");
+
+ BOOST_TEST(!v.empty()); //check if a symbols was found.
+
+
+ v = ms.get_function<const int &()>("some_space::scoped_fun");
+
+ BOOST_TEST(!v.empty());
+ BOOST_TEST(v != "some_space::scoped_fun");
+
+
+ auto v1 = ms.get_function<void(const double)>("overloaded");
+ auto v2 = ms.get_function<void(const volatile int)>("overloaded");
+ BOOST_TEST(!v1.empty());
+ BOOST_TEST(!v2.empty());
+ BOOST_TEST(v1 != v2);
+
+ v = ms.get_variable<int>("some_space::some_class::value");
+ BOOST_TEST(!v.empty());
+ BOOST_TEST(v != "some_space::some_class::value");
+
+ v = ms.get_function<void(const int &)>("some_space::some_class::set_value");
+
+ BOOST_TEST(!v.empty());
+ BOOST_TEST(v != "some_space::some_class::set_value");
+
+
+
+ ms.add_alias<override_class>("some_space::some_class");
+
+ auto ctor1 = ms.get_constructor<override_class()>();
+ BOOST_TEST(!ctor1.empty());
+
+ auto ctor2 = ms.get_constructor<override_class(int)>();
+ BOOST_TEST(!ctor2.empty());
+
+
+ v = ms.get_mem_fn<override_class, double(double, double)>("func");
+ BOOST_TEST(!v.empty());
+
+ v = ms.get_mem_fn<override_class, int(int, int)>("func");
+ BOOST_TEST(!v.empty());
+
+
+ auto dtor = ms.get_destructor<override_class>();
+
+ BOOST_TEST(!dtor.empty());
+
+// TODO: ms.get_name on Clang has space after comma `boost::variant<double, int>`
+#if !(defined(BOOST_TRAVISCI_BUILD) && defined(_MSC_VER) && defined(BOOST_CLANG))
+ auto var1 = ms.get_function<void(boost::variant<int, double> &)>("use_variant");
+ auto var2 = ms.get_function<void(boost::variant<double, int> &)>("use_variant");
+
+ BOOST_TEST(!var1.empty());
+ BOOST_TEST(!var2.empty());
+#endif
+
+#ifndef BOOST_NO_RTTI
+
+#if defined(_MSC_VER) // MSVC, Clang-cl, and ICC on Windows
+ auto vtable = ms.get_vtable<override_class>();
+ BOOST_TEST(!vtable.empty());
+#else
+ auto ti = ms.get_type_info<override_class>();
+ BOOST_TEST(!ti.empty());
+#endif
+
+#endif // #ifndef BOOST_NO_RTTI
+
+ return boost::report_errors();
+}
+
+#else
+int main() {return 0;}
+#endif
diff --git a/src/boost/libs/dll/test/cpp_test_library.cpp b/src/boost/libs/dll/test/cpp_test_library.cpp
new file mode 100644
index 000000000..f32a3376a
--- /dev/null
+++ b/src/boost/libs/dll/test/cpp_test_library.cpp
@@ -0,0 +1,203 @@
+// Copyright 2016 Klemens Morgenstern
+// Copyright 2017-2019 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/predef.h>
+
+#if (__cplusplus >= 201402L) || (BOOST_COMP_MSVC >= BOOST_VERSION_NUMBER(14,0,0))
+
+#include <boost/dll/config.hpp>
+#include <boost/variant.hpp>
+
+BOOST_SYMBOL_EXPORT extern int unscoped_var;
+int unscoped_var = 42;
+
+BOOST_SYMBOL_EXPORT extern const double unscoped_c_var;
+const double unscoped_c_var = 1.234;
+
+
+namespace some_space {
+
+BOOST_SYMBOL_EXPORT extern double variable;
+double variable = 0.2;
+BOOST_SYMBOL_EXPORT const int & scoped_fun()
+{
+ static int x = 0xDEADBEEF;
+ return x;
+}
+
+}
+
+
+BOOST_SYMBOL_EXPORT void overloaded(const volatile int i)
+{
+ unscoped_var = i;
+}
+
+BOOST_SYMBOL_EXPORT void overloaded(const double d)
+{
+ some_space::variable = d;
+}
+
+BOOST_SYMBOL_EXPORT void use_variant(boost::variant<int, double> & v)
+{
+ v = 42;
+}
+
+BOOST_SYMBOL_EXPORT void use_variant(boost::variant<double, int> & v)
+{
+ v = 3.124;
+}
+
+
+
+namespace some_space
+{
+
+BOOST_SYMBOL_EXPORT extern int father_value;
+int father_value = 12;
+
+struct BOOST_SYMBOL_EXPORT some_father
+{
+ some_father() { father_value = 24; };
+ ~some_father() { father_value = 112; };
+};
+
+
+
+struct BOOST_SYMBOL_EXPORT some_class : some_father
+{
+ static int value ;
+ static void set_value(const int &i);
+
+ // static some_class* dummy();
+
+ virtual double func(double i, double j);
+ virtual int func(int i, int j);
+ int func(int i, int j) volatile;
+ double func(double i, double j) const volatile;
+
+ int mem_val;
+ int get() const ;
+ void set(int i) ;
+
+ some_class();
+ some_class(some_class &&);
+ some_class(int i);
+
+ some_class& operator=(some_class &&);
+
+
+ virtual ~some_class();
+};
+
+some_class::some_class(some_class &&){}
+
+
+some_class& some_class::operator=(some_class &&ref) {return ref;}
+
+
+BOOST_SYMBOL_EXPORT extern std::size_t size_of_some_class;
+std::size_t size_of_some_class = sizeof(some_space::some_class);
+
+
+extern "C" BOOST_SYMBOL_EXPORT const volatile some_class* this_;
+const volatile some_class * this_ = nullptr;
+
+int some_class::value = -1;
+
+void some_class::set_value(const int &i) {value = i;}
+
+
+//some_class* some_class::dummy() {return new some_class();}//so it implements an allocating ctor.
+
+double some_class::func(double i, double j) {this_ = this; return i*j;}
+int some_class::func(int i, int j) {this_ = this; return i+j;}
+int some_class::func(int i, int j) volatile {this_ = this; return i-j;;}
+double some_class::func(double i, double j) const volatile {this_ = this; return i/j;}
+
+int some_class::get() const {this_ = this; return mem_val;}
+void some_class::set(int i) {this_ = this; mem_val = i;}
+
+some_class::some_class() { this_ = this; value = 23; mem_val = 123;}
+some_class::some_class(int i) : mem_val(456) {this_ = this; value = i;}
+
+some_class::~some_class()
+{
+ value = 0;
+ this_ = this;
+}
+
+}
+
+namespace space {
+ class BOOST_SYMBOL_EXPORT my_plugin;
+}
+
+namespace testing { namespace space {
+ class BOOST_SYMBOL_EXPORT my_plugin {
+ public:
+ template<typename Arg>
+ BOOST_SYMBOL_EXPORT int Func() const;
+ template<typename Arg>
+ BOOST_SYMBOL_EXPORT int Func();
+ template<typename Arg>
+ BOOST_SYMBOL_EXPORT int Func2();
+ template<typename Arg>
+ BOOST_SYMBOL_EXPORT int AFunc();
+ };
+
+ template<typename Arg>
+ BOOST_SYMBOL_EXPORT int my_plugin::Func() const { return 30; }
+
+ template<typename Arg>
+ BOOST_SYMBOL_EXPORT int my_plugin::Func() { return 32; }
+
+ template<typename Arg>
+ BOOST_SYMBOL_EXPORT int my_plugin::Func2() { return 33; }
+
+ template<typename Arg>
+ BOOST_SYMBOL_EXPORT int my_plugin::AFunc() { return 31; }
+
+ template BOOST_SYMBOL_EXPORT int my_plugin::Func<::space::my_plugin>();
+ template BOOST_SYMBOL_EXPORT int my_plugin::Func2<::space::my_plugin>();
+ template BOOST_SYMBOL_EXPORT int my_plugin::AFunc<::space::my_plugin>();
+}}
+
+namespace space {
+ class BOOST_SYMBOL_EXPORT my_plugin {
+ public:
+ template<typename Arg>
+ BOOST_SYMBOL_EXPORT int Func() const;
+ template<typename Arg>
+ BOOST_SYMBOL_EXPORT int Func();
+ template<typename Arg>
+ BOOST_SYMBOL_EXPORT int Func2();
+ template<typename Arg>
+ BOOST_SYMBOL_EXPORT int AFunc();
+ };
+
+ template<typename Arg>
+ BOOST_SYMBOL_EXPORT int my_plugin::Func() const { return 40; }
+
+ template<typename Arg>
+ BOOST_SYMBOL_EXPORT int my_plugin::Func() { return 42; }
+
+ template<typename Arg>
+ BOOST_SYMBOL_EXPORT int my_plugin::Func2() { return 43; }
+
+ template<typename Arg>
+ BOOST_SYMBOL_EXPORT int my_plugin::AFunc() { return 41; }
+
+ template BOOST_SYMBOL_EXPORT int my_plugin::Func<::space::my_plugin>();
+ template BOOST_SYMBOL_EXPORT int my_plugin::Func2<::space::my_plugin>();
+ template BOOST_SYMBOL_EXPORT int my_plugin::AFunc<::space::my_plugin>();
+}
+
+
+#endif
diff --git a/src/boost/libs/dll/test/library_info_test.cpp b/src/boost/libs/dll/test/library_info_test.cpp
new file mode 100644
index 000000000..e7808e961
--- /dev/null
+++ b/src/boost/libs/dll/test/library_info_test.cpp
@@ -0,0 +1,65 @@
+// Copyright 2011-2012 Renato Tegon Forti
+// Copyright 2015-2019 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
+
+// MinGW related workaround
+#define BOOST_DLL_FORCE_ALIAS_INSTANTIATION
+#include "../example/b2_workarounds.hpp"
+
+#include <boost/dll/library_info.hpp>
+#include <boost/core/lightweight_test.hpp>
+#include "../example/tutorial4/static_plugin.hpp"
+
+// Unit Tests
+
+#include <iterator>
+
+int main(int argc, char* argv[])
+{
+ boost::dll::fs::path shared_library_path = b2_workarounds::first_lib_from_argv(argc, argv);
+ BOOST_TEST(shared_library_path.string().find("test_library") != std::string::npos);
+
+ boost::dll::library_info lib_info(shared_library_path);
+ std::vector<std::string> sec = lib_info.sections();
+ std::copy(sec.begin(), sec.end(), std::ostream_iterator<std::string>(std::cout, ", "));
+ BOOST_TEST(std::find(sec.begin(), sec.end(), "boostdll") != sec.end());
+
+
+ std::cout << "\n\n\n";
+ std::vector<std::string> symb = lib_info.symbols();
+ 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") != symb.end());
+ BOOST_TEST(std::find(symb.begin(), symb.end(), "say_hello") != symb.end());
+
+ 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());
+ BOOST_TEST(std::find(symb.begin(), symb.end(), "foo_variable") != symb.end());
+ BOOST_TEST(std::find(symb.begin(), symb.end(), "const_integer_g") == symb.end());
+ BOOST_TEST(std::find(symb.begin(), symb.end(), "say_hello") == symb.end());
+ BOOST_TEST(lib_info.symbols(std::string("boostdll")) == symb);
+
+ std::vector<std::string> empty = lib_info.symbols("empty");
+ BOOST_TEST(empty.empty() == true);
+
+ BOOST_TEST(lib_info.symbols("section_that_does_not_exist").empty());
+
+ // Self testing
+ std::cout << "Self: " << argv[0];
+ boost::dll::library_info self_info(argv[0]);
+
+ sec = self_info.sections();
+ //std::copy(sec.begin(), sec.end(), std::ostream_iterator<std::string>(std::cout, ", "));
+ BOOST_TEST(std::find(sec.begin(), sec.end(), "boostdll") != sec.end());
+
+ symb = self_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(), "create_plugin") != symb.end());
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/dll/test/link.hpp b/src/boost/libs/dll/test/link.hpp
new file mode 100644
index 000000000..f84d8bd34
--- /dev/null
+++ b/src/boost/libs/dll/test/link.hpp
@@ -0,0 +1,21 @@
+// Copyright 2018-2019 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/predef.h>
+
+#if (__cplusplus >= 201402L) || (BOOST_COMP_MSVC >= BOOST_VERSION_NUMBER(14,0,0))
+
+#include <boost/dll/smart_library.hpp>
+#include <boost/dll/import_mangled.hpp>
+#include <boost/dll/import_class.hpp>
+
+#endif
+
+
+#include <boost/dll.hpp>
diff --git a/src/boost/libs/dll/test/link1.cpp b/src/boost/libs/dll/test/link1.cpp
new file mode 100644
index 000000000..639e827cf
--- /dev/null
+++ b/src/boost/libs/dll/test/link1.cpp
@@ -0,0 +1,10 @@
+// Copyright 2018-2019 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 "link.hpp"
diff --git a/src/boost/libs/dll/test/link2.cpp b/src/boost/libs/dll/test/link2.cpp
new file mode 100644
index 000000000..670d39069
--- /dev/null
+++ b/src/boost/libs/dll/test/link2.cpp
@@ -0,0 +1,12 @@
+// Copyright 2018-2019 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 "link.hpp"
+
+int main() {}
diff --git a/src/boost/libs/dll/test/section_name_too_big.cpp b/src/boost/libs/dll/test/section_name_too_big.cpp
new file mode 100644
index 000000000..03db48f5c
--- /dev/null
+++ b/src/boost/libs/dll/test/section_name_too_big.cpp
@@ -0,0 +1,17 @@
+// Copyright 2011-2012 Renato Tegon Forti
+// Copyright 2014 Renato Tegon Forti, Antony Polukhin.
+// Copyright 2015-2019 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
+
+#define BOOST_DLL_FORCE_ALIAS_INSTANTIATION
+#include <boost/dll/config.hpp>
+#include <boost/dll/alias.hpp>
+
+int integer_g = 100;
+BOOST_DLL_ALIAS_SECTIONED(integer_g, integer_g_aliased, "long_section_name")
+
diff --git a/src/boost/libs/dll/test/shared_library_concurrent_load_test.cpp b/src/boost/libs/dll/test/shared_library_concurrent_load_test.cpp
new file mode 100644
index 000000000..e97926b7e
--- /dev/null
+++ b/src/boost/libs/dll/test/shared_library_concurrent_load_test.cpp
@@ -0,0 +1,82 @@
+// Copyright 2015-2019 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
+
+#ifdef BOOST_TRAVISCI_BUILD
+
+int main() {
+ return 0;
+}
+
+#else // #ifdef BOOST_TRAVISCI_BUILD
+
+#include "../example/b2_workarounds.hpp"
+#include <boost/dll.hpp>
+#include <boost/filesystem/path.hpp>
+#include <boost/thread/thread.hpp>
+#include <boost/thread/barrier.hpp>
+#include <boost/core/lightweight_test.hpp>
+#include <boost/bind.hpp>
+#include <cctype>
+#include <vector>
+
+typedef std::vector<boost::dll::fs::path> paths_t;
+const std::size_t thread_count = 4;
+boost::barrier b(thread_count);
+
+
+// Disgusting workarounds for b2 on Windows platform
+inline paths_t generate_paths(int argc, char* argv[]) {
+ paths_t ret;
+ ret.reserve(argc - 1);
+
+ for (int i = 1; i < argc; ++i) {
+ boost::dll::fs::path p = argv[i];
+ if (b2_workarounds::is_shared_library(p)) {
+ ret.push_back(p);
+ }
+ }
+
+ return ret;
+}
+
+inline void load_unload(const paths_t& paths, std::size_t count) {
+ for (std::size_t j = 0; j < count; j += 2) {
+ for (std::size_t i = 0; i < paths.size(); ++i) {
+ boost::dll::shared_library lib(paths[i]);
+ BOOST_TEST(lib);
+ }
+ for (std::size_t i = 0; i < paths.size(); ++i) {
+ boost::dll::shared_library lib(paths[i]);
+ BOOST_TEST(lib.location() != "");
+ }
+
+ // Waiting for all threads to unload shared libraries
+ b.wait();
+ }
+}
+
+
+int main(int argc, char* argv[]) {
+ BOOST_TEST(argc >= 3);
+ paths_t paths = generate_paths(argc, argv);
+ BOOST_TEST(!paths.empty());
+
+ std::cout << "Libraries:\n\t";
+ std::copy(paths.begin(), paths.end(), std::ostream_iterator<boost::dll::fs::path>(std::cout, ", "));
+ std::cout << std::endl;
+
+ boost::thread_group threads;
+ for (std::size_t i = 0; i < thread_count; ++i) {
+ threads.create_thread(boost::bind(load_unload, paths, 1000));
+ }
+ threads.join_all();
+
+ return boost::report_errors();
+}
+
+#endif // #ifdef BOOST_TRAVISCI_BUILD
diff --git a/src/boost/libs/dll/test/shared_library_errors.cpp b/src/boost/libs/dll/test/shared_library_errors.cpp
new file mode 100644
index 000000000..2f186fe1b
--- /dev/null
+++ b/src/boost/libs/dll/test/shared_library_errors.cpp
@@ -0,0 +1,100 @@
+// Copyright 2011-2012 Renato Tegon Forti.
+// Copyright 2014 Renato Tegon Forti, Antony Polukhin.
+// Copyright 2015-2019 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 "../example/b2_workarounds.hpp"
+#include <boost/dll/shared_library.hpp>
+#include <boost/dll/library_info.hpp>
+#include <boost/core/lightweight_test.hpp>
+#include <boost/function.hpp>
+
+
+// Unit Tests
+int main(int argc, char* argv[]) {
+ using namespace boost::dll;
+
+ boost::dll::fs::path shared_library_path = b2_workarounds::first_lib_from_argv(argc, argv);
+ BOOST_TEST(shared_library_path.string().find("test_library") != std::string::npos);
+ BOOST_TEST(b2_workarounds::is_shared_library(shared_library_path));
+ boost::dll::fs::path bad_path = shared_library_path / "directory_that_does_not_exist";
+
+ try {
+ shared_library lib(bad_path);
+ BOOST_TEST(false);
+ } catch (const boost::dll::fs::system_error& e) {
+ std::cout << e.what() << '\n';
+ }
+
+ try {
+ shared_library lib;
+ lib.get<int>("variable_or_function_that_does_not_exist");
+ BOOST_TEST(false);
+ } catch (const boost::dll::fs::system_error& e) {
+ std::cout << e.what() << '\n';
+ }
+
+ try {
+ shared_library lib("");
+ BOOST_TEST(false);
+ } catch (const boost::dll::fs::system_error& e) {
+ std::cout << e.what() << '\n';
+ }
+
+ try {
+ shared_library lib("\0\0");
+ BOOST_TEST(false);
+ } catch (const boost::dll::fs::system_error& e) {
+ std::cout << e.what() << '\n';
+ }
+
+ try {
+ shared_library lib;
+ lib.location();
+ BOOST_TEST(false);
+ } catch (const boost::dll::fs::system_error& e) {
+ std::cout << e.what() << '\n';
+ }
+
+ try {
+ shared_library lib;
+ lib.load("\0\0", load_mode::rtld_global);
+ BOOST_TEST(false);
+ } catch (const boost::dll::fs::system_error& e) {
+ std::cout << e.what() << '\n';
+ }
+
+ shared_library sl(shared_library_path);
+ try {
+ sl.get<int>("variable_or_function_that_does_not_exist");
+ BOOST_TEST(false);
+ } catch (const boost::dll::fs::system_error& e) {
+ std::cout << e.what() << '\n';
+ }
+
+ try {
+ library_info lib("\0");
+ BOOST_TEST(false);
+ } catch (const std::exception& e) {
+ std::cout << e.what() << '\n';
+ }
+
+ try {
+ std::string not_a_binary(argv[1]);
+ not_a_binary += "/not_a_binary";
+ std::ofstream ofs(not_a_binary.c_str());
+ ofs << "This is not a binary file, so library_info must report 'Unsupported binary format'";
+ ofs.close();
+ library_info lib(not_a_binary);
+ BOOST_TEST(false);
+ } catch (const std::exception& e) {
+ std::cout << e.what() << '\n';
+ }
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/dll/test/shared_library_get_symbol_test.cpp b/src/boost/libs/dll/test/shared_library_get_symbol_test.cpp
new file mode 100644
index 000000000..82e524d3d
--- /dev/null
+++ b/src/boost/libs/dll/test/shared_library_get_symbol_test.cpp
@@ -0,0 +1,193 @@
+// Copyright 2011-2012 Renato Tegon Forti.
+// Copyright 2014 Renato Tegon Forti, Antony Polukhin.
+// Copyright 2015-2019 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 "../example/b2_workarounds.hpp"
+#include <boost/dll.hpp>
+#include <boost/core/lightweight_test.hpp>
+#include <boost/function.hpp>
+#include <boost/fusion/container.hpp>
+// lib functions
+
+typedef float (lib_version_func)();
+typedef void (say_hello_func) ();
+typedef int (increment) (int);
+
+typedef boost::fusion::vector<std::vector<int>, std::vector<int>, std::vector<int>, const std::vector<int>*, std::vector<int>* > do_share_res_t;
+typedef boost::shared_ptr<do_share_res_t> (do_share_t)(
+ std::vector<int> v1,
+ std::vector<int>& v2,
+ const std::vector<int>& v3,
+ const std::vector<int>* v4,
+ std::vector<int>* v5
+ );
+
+void refcountable_test(boost::dll::fs::path shared_library_path) {
+ using namespace boost::dll;
+ using namespace boost::fusion;
+
+ std::vector<int> v(1000);
+
+ {
+ boost::function<say_hello_func> sz2
+ = import<say_hello_func>(shared_library_path, "say_hello");
+
+ sz2();
+ sz2();
+ sz2();
+ }
+
+ {
+ boost::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;
+
+ {
+ boost::function<do_share_t> f2 = import_alias<do_share_t>(shared_library_path, "do_share");
+ f = f2;
+ }
+
+ std::vector<int> v1(1, 1), v2(2, 2), v3(3, 3), v4(4, 4), v5(1000, 5);
+ boost::shared_ptr<do_share_res_t> res = f(v1, v2, v3, &v4, &v5);
+
+ BOOST_TEST(at_c<0>(*res).size() == 1); BOOST_TEST(at_c<0>(*res).front() == 1);
+ BOOST_TEST(at_c<1>(*res).size() == 2); BOOST_TEST(at_c<1>(*res).front() == 2);
+ BOOST_TEST(at_c<2>(*res).size() == 3); BOOST_TEST(at_c<2>(*res).front() == 3);
+ BOOST_TEST(at_c<3>(*res)->size() == 4); BOOST_TEST(at_c<3>(*res)->front() == 4);
+ BOOST_TEST(at_c<4>(*res)->size() == 1000); BOOST_TEST(at_c<4>(*res)->front() == 5);
+
+ BOOST_TEST(at_c<3>(*res) == &v4);
+ BOOST_TEST(at_c<4>(*res) == &v5);
+ BOOST_TEST(at_c<1>(*res).back() == 777);
+ BOOST_TEST(v5.back() == 9990);
+ }
+
+ {
+ boost::shared_ptr<int> i = import<int>(shared_library_path, "integer_g");
+ BOOST_TEST(*i == 100);
+
+ boost::shared_ptr<int> i2;
+ i.swap(i2);
+ BOOST_TEST(*i2 == 100);
+ }
+
+ {
+ boost::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");
+ BOOST_TEST(f1() == 10);
+
+ f1() += 10;
+ BOOST_TEST(f() == 20);
+ }
+
+ {
+ boost::shared_ptr<const int> i = import<const int>(shared_library_path, "const_integer_g");
+ BOOST_TEST(*i == 777);
+
+ boost::shared_ptr<const int> i2 = i;
+ i.reset();
+ BOOST_TEST(*i2 == 777);
+ }
+
+ {
+ boost::shared_ptr<std::string> s = import_alias<std::string>(shared_library_path, "info");
+ BOOST_TEST(*s == "I am a std::string from the test_library (Think of me as of 'Hello world'. Long 'Hello world').");
+
+ boost::shared_ptr<std::string> s2;
+ s.swap(s2);
+ BOOST_TEST(*s2 == "I am a std::string from the test_library (Think of me as of 'Hello world'. Long 'Hello world').");
+ }
+}
+
+// exe function
+extern "C" int BOOST_SYMBOL_EXPORT exef() {
+ return 15;
+}
+
+// Unit Tests
+int main(int argc, char* argv[]) {
+ using namespace boost::dll;
+
+ boost::dll::fs::path shared_library_path = b2_workarounds::first_lib_from_argv(argc, argv);
+ BOOST_TEST(shared_library_path.string().find("test_library") != std::string::npos);
+ BOOST_TEST(b2_workarounds::is_shared_library(shared_library_path));
+
+ refcountable_test(shared_library_path);
+
+ shared_library sl(shared_library_path);
+
+ BOOST_TEST(sl.get<int>("integer_g") == 100);
+
+ sl.get<int>("integer_g") = 10;
+ BOOST_TEST(sl.get<int>("integer_g") == 10);
+ BOOST_TEST(sl.get<int>(std::string("integer_g")) == 10);
+
+ BOOST_TEST(sl.get<say_hello_func>("say_hello"));
+ sl.get<say_hello_func>("say_hello")();
+
+ float ver = sl.get<lib_version_func>("lib_version")();
+ BOOST_TEST(ver == 1.0);
+
+ int n = sl.get<increment>("increment")(1);
+ BOOST_TEST(n == 2);
+
+ BOOST_TEST(sl.get<const int>("const_integer_g") == 777);
+
+ boost::function<int(int)> inc = sl.get<int(int)>("increment");
+ BOOST_TEST(inc(1) == 2);
+ BOOST_TEST(inc(2) == 3);
+ BOOST_TEST(inc(3) == 4);
+
+ // Checking that symbols are still available, after another load+unload of the library
+ { shared_library sl2(shared_library_path); }
+
+ BOOST_TEST(inc(1) == 2);
+ BOOST_TEST(sl.get<int>("integer_g") == 10);
+
+
+ // Checking aliases
+ boost::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);
+ BOOST_TEST(sz(v) == 10);
+ BOOST_TEST(sl.get_alias<std::size_t>("foo_variable") == 42);
+
+
+ sz = sl.get<std::size_t(*)(const std::vector<int>&)>("foo_bar");
+ BOOST_TEST(sz(v) == 10);
+ BOOST_TEST(*sl.get<std::size_t*>("foo_variable") == 42);
+
+ { // self
+ shared_library sl(program_location());
+ int val = sl.get<int(void)>("exef")();
+ BOOST_TEST(val == 15);
+ }
+
+ int& reference_to_internal_integer = sl.get<int&>("reference_to_internal_integer");
+ BOOST_TEST(reference_to_internal_integer == 0xFF0000);
+
+#ifndef BOOST_NO_RVALUE_REFERENCES
+ int&& rvalue_reference_to_internal_integer = sl.get<int&&>("rvalue_reference_to_internal_integer");
+ BOOST_TEST(rvalue_reference_to_internal_integer == 0xFF0000);
+#endif
+
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/dll/test/shared_library_load_test.cpp b/src/boost/libs/dll/test/shared_library_load_test.cpp
new file mode 100644
index 000000000..de7e619ee
--- /dev/null
+++ b/src/boost/libs/dll/test/shared_library_load_test.cpp
@@ -0,0 +1,528 @@
+// Copyright 2011-2012 Renato Tegon Forti
+// Copyright 2015-2019 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 "../example/b2_workarounds.hpp"
+#include <boost/dll.hpp>
+#include <boost/core/lightweight_test.hpp>
+// Unit Tests
+
+namespace boost { namespace dll { namespace fs {
+
+#ifdef BOOST_DLL_USE_STD_FS
+using std::filesystem::remove;
+using std::filesystem::copy;
+#else
+using boost::filesystem::remove;
+using boost::filesystem::copy;
+#endif
+
+}}}
+
+inline boost::dll::fs::path drop_version(const boost::dll::fs::path& lhs) {
+ boost::dll::fs::path ext = lhs.filename().extension();
+ if (ext.native().size() > 1 && std::isdigit(ext.string()[1])) {
+ ext = lhs;
+ ext.replace_extension().replace_extension().replace_extension();
+ return ext;
+ }
+
+ return lhs;
+}
+
+inline bool lib_path_equal(const boost::dll::fs::path& lhs, const boost::dll::fs::path& rhs) {
+ const bool res = (drop_version(lhs).filename() == drop_version(rhs).filename());
+ if (!res) {
+ std::cerr << "lhs != rhs: " << lhs << " != " << rhs << '\n';
+ }
+ return res;
+}
+
+struct fs_copy_guard {
+ const boost::dll::fs::path actual_path_;
+ const bool same_;
+
+ inline explicit fs_copy_guard(const boost::dll::fs::path& shared_library_path)
+ : actual_path_( drop_version(shared_library_path) )
+ , same_(actual_path_ == shared_library_path)
+ {
+ if (!same_) {
+ boost::dll::fs::error_code ignore;
+ boost::dll::fs::remove(actual_path_, ignore);
+ boost::dll::fs::copy(shared_library_path, actual_path_, ignore);
+ }
+ }
+
+ inline ~fs_copy_guard() {
+ if (!same_) {
+ boost::dll::fs::error_code ignore;
+ boost::dll::fs::remove(actual_path_, ignore);
+ }
+ }
+};
+
+// Disgusting workarounds for b2 on Windows platform
+inline boost::dll::fs::path do_find_correct_libs_path(int argc, char* argv[], const char* lib_name) {
+ boost::dll::fs::path ret;
+
+ for (int i = 1; i < argc; ++i) {
+ ret = argv[i];
+ if (ret.string().find(lib_name) != std::string::npos && b2_workarounds::is_shared_library(ret)) {
+ return ret;
+ }
+ }
+
+ return lib_name;
+}
+
+int main(int argc, char* argv[])
+{
+ using namespace boost::dll;
+
+ BOOST_TEST(argc >= 3);
+ boost::dll::fs::path shared_library_path = do_find_correct_libs_path(argc, argv, "test_library");
+ std::cout << "Library: " << shared_library_path;
+
+ {
+ shared_library sl(shared_library_path);
+ BOOST_TEST(sl.is_loaded());
+ BOOST_TEST(lib_path_equal(sl.location(), shared_library_path));
+
+ shared_library sl2;
+ BOOST_TEST(!sl2.is_loaded());
+ BOOST_TEST(!sl2);
+
+ swap(sl, sl2);
+ BOOST_TEST(!sl.is_loaded());
+ BOOST_TEST(!sl);
+ BOOST_TEST(sl2.is_loaded());
+ BOOST_TEST(sl2);
+
+ sl.assign(sl2);
+ BOOST_TEST(sl.is_loaded());
+ BOOST_TEST(sl);
+ BOOST_TEST(sl2.is_loaded());
+ BOOST_TEST(sl2);
+ BOOST_TEST(sl2.location() == sl.location());
+
+ sl.assign(sl2);
+ BOOST_TEST(sl.is_loaded());
+ BOOST_TEST(sl);
+ BOOST_TEST(sl2.is_loaded());
+ BOOST_TEST(sl2);
+ BOOST_TEST(sl2.location() == sl.location());
+
+ sl2.assign(sl);
+ BOOST_TEST(sl.is_loaded());
+ BOOST_TEST(sl);
+ BOOST_TEST(sl2.is_loaded());
+ BOOST_TEST(sl2);
+ BOOST_TEST(sl2.location() == sl.location());
+
+ // Assigning an empty shared library
+ sl2.assign(shared_library());
+ BOOST_TEST(sl.is_loaded());
+ BOOST_TEST(sl);
+ BOOST_TEST(!sl2.is_loaded());
+ BOOST_TEST(!sl2);
+ boost::dll::fs::error_code ec;
+ BOOST_TEST(sl2.location(ec) != sl.location());
+ BOOST_TEST(ec);
+ }
+
+ {
+ boost::dll::fs::error_code ec;
+ shared_library sl(shared_library_path, ec);
+ BOOST_TEST(sl.is_loaded());
+ BOOST_TEST(sl);
+ BOOST_TEST(!ec);
+ BOOST_TEST(lib_path_equal(sl.location(), shared_library_path));
+ BOOST_TEST(lib_path_equal(sl.location(ec), shared_library_path));
+ BOOST_TEST(!ec);
+
+ // Checking self assignment #1
+ sl.assign(sl);
+ BOOST_TEST(sl.is_loaded());
+ BOOST_TEST(sl);
+ BOOST_TEST(!ec);
+ BOOST_TEST(lib_path_equal(sl.location(), shared_library_path));
+ BOOST_TEST(lib_path_equal(sl.location(ec), shared_library_path));
+
+ // Checking self assignment #2
+ sl.assign(sl, ec);
+ BOOST_TEST(sl.is_loaded());
+ BOOST_TEST(sl);
+ BOOST_TEST(!ec);
+ BOOST_TEST(lib_path_equal(sl.location(), shared_library_path));
+ BOOST_TEST(lib_path_equal(sl.location(ec), shared_library_path));
+ }
+
+ {
+ shared_library sl;
+ BOOST_TEST(!sl.is_loaded());
+
+ sl.assign(sl);
+ BOOST_TEST(!sl);
+
+ shared_library sl2(sl);
+ BOOST_TEST(!sl);
+ BOOST_TEST(!sl2);
+
+ sl2.assign(sl);
+ BOOST_TEST(!sl);
+ BOOST_TEST(!sl2);
+ }
+
+ {
+ shared_library sl;
+ sl.load(shared_library_path);
+ BOOST_TEST(sl.is_loaded());
+ BOOST_TEST(sl);
+ BOOST_TEST(lib_path_equal(sl.location(), shared_library_path));
+ }
+
+ {
+ shared_library sl;
+ boost::dll::fs::error_code ec;
+ sl.load(shared_library_path, ec);
+ BOOST_TEST(sl.is_loaded());
+ BOOST_TEST(sl);
+ BOOST_TEST(!ec);
+ BOOST_TEST(lib_path_equal(sl.location(), shared_library_path));
+ }
+
+ {
+ shared_library sl(shared_library_path, load_mode::load_with_altered_search_path );
+ BOOST_TEST(sl.is_loaded());
+ BOOST_TEST(sl);
+ BOOST_TEST(lib_path_equal(sl.location(), shared_library_path));
+ }
+
+ {
+ boost::dll::fs::error_code ec;
+ shared_library sl(shared_library_path, load_mode::load_with_altered_search_path, ec);
+ BOOST_TEST(sl.is_loaded());
+ BOOST_TEST(sl);
+ BOOST_TEST(!ec);
+ BOOST_TEST(lib_path_equal(sl.location(), shared_library_path));
+ BOOST_TEST(lib_path_equal(sl.location(ec), shared_library_path));
+ BOOST_TEST(!ec);
+ }
+
+ {
+ boost::dll::fs::error_code ec;
+ shared_library sl(shared_library_path, load_mode::search_system_folders, ec);
+ BOOST_TEST(sl.is_loaded());
+ BOOST_TEST(sl);
+ BOOST_TEST(!ec);
+ BOOST_TEST(lib_path_equal(sl.location(), shared_library_path));
+ BOOST_TEST(lib_path_equal(sl.location(ec), shared_library_path));
+ BOOST_TEST(!ec);
+ }
+
+ {
+ try {
+#if BOOST_OS_WINDOWS
+ boost::dll::shared_library("winmm.dll");
+#elif BOOST_OS_LINUX
+ boost::dll::shared_library("libdl.so");
+#endif
+ BOOST_TEST(false);
+ } catch (...) {}
+ }
+
+ {
+ try {
+#if BOOST_OS_WINDOWS
+ boost::dll::shared_library("winmm", load_mode::search_system_folders | load_mode::append_decorations);
+#elif BOOST_OS_LINUX
+ boost::dll::shared_library("dl", boost::dll::load_mode::search_system_folders | load_mode::append_decorations);
+#endif
+ } catch (...) {
+ BOOST_TEST(false);
+ }
+ }
+
+ {
+ shared_library sl;
+ sl.load(shared_library_path, load_mode::load_with_altered_search_path);
+ BOOST_TEST(sl.is_loaded());
+ BOOST_TEST(sl);
+ BOOST_TEST(lib_path_equal(sl.location(), shared_library_path));
+ }
+
+ {
+ shared_library sl;
+ boost::dll::fs::error_code ec;
+ sl.load(shared_library_path, load_mode::load_with_altered_search_path, ec);
+ BOOST_TEST(sl.is_loaded());
+ BOOST_TEST(sl);
+ BOOST_TEST(lib_path_equal(sl.location(), shared_library_path));
+ }
+
+ {
+ shared_library sl(shared_library_path, load_mode::rtld_lazy | load_mode::rtld_global);
+ BOOST_TEST(sl.is_loaded());
+ BOOST_TEST(sl);
+ BOOST_TEST(lib_path_equal(sl.location(), shared_library_path));
+ }
+
+ {
+ shared_library sl(shared_library_path, load_mode::rtld_local);
+ BOOST_TEST(sl.is_loaded());
+ BOOST_TEST(sl);
+ BOOST_TEST(lib_path_equal(sl.location(), shared_library_path));
+ }
+
+ {
+ shared_library sl(shared_library_path, load_mode::rtld_now);
+ BOOST_TEST(sl.is_loaded());
+ BOOST_TEST(sl);
+ BOOST_TEST(lib_path_equal(sl.location(), shared_library_path));
+ }
+
+ {
+ fs_copy_guard guard(shared_library_path);
+
+ boost::dll::fs::path platform_independent_path = guard.actual_path_;
+ platform_independent_path.replace_extension();
+ if (platform_independent_path.filename().wstring().find(L"lib") == 0) {
+ platform_independent_path
+ = platform_independent_path.parent_path() / platform_independent_path.filename().wstring().substr(3);
+ }
+ std::cerr << "platform_independent_path: " << platform_independent_path << '\n';
+
+ shared_library sl(platform_independent_path, load_mode::append_decorations);
+ BOOST_TEST(sl.is_loaded());
+ BOOST_TEST(sl);
+ BOOST_TEST(lib_path_equal(sl.location(), shared_library_path));
+
+ sl.unload();
+ BOOST_TEST(!sl.is_loaded());
+ BOOST_TEST(!sl);
+ }
+
+ {
+ shared_library sl(shared_library_path, load_mode::rtld_now | load_mode::rtld_global | load_mode::load_with_altered_search_path);
+ BOOST_TEST(sl.is_loaded());
+ BOOST_TEST(sl);
+ }
+
+ {
+ boost::dll::fs::error_code ec;
+ shared_library sl(shared_library_path, load_mode::rtld_lazy | load_mode::rtld_global, ec);
+ BOOST_TEST(sl.is_loaded());
+ BOOST_TEST(sl);
+ BOOST_TEST(!ec);
+ BOOST_TEST(lib_path_equal(sl.location(), shared_library_path));
+ }
+
+ {
+ shared_library sl;
+ sl.load(shared_library_path, load_mode::rtld_lazy | load_mode::rtld_global);
+ BOOST_TEST(sl.is_loaded());
+ BOOST_TEST(sl);
+ BOOST_TEST(lib_path_equal(sl.location(), shared_library_path));
+ }
+
+
+ { // Non-default flags with assignment
+ shared_library sl(shared_library_path,
+ load_mode::rtld_now | load_mode::rtld_global | load_mode::load_with_altered_search_path
+
+// `load_mode::rtld_deepbind` is incompatible with sanitizers:
+// You are trying to dlopen a libtest_library.so shared library with RTLD_DEEPBIND flag which is incompatibe with sanitizer runtime
+// (see https://github.com/google/sanitizers/issues/611 for details).
+#ifndef BOOST_TRAVISCI_BUILD
+ | load_mode::rtld_deepbind
+#endif
+
+ );
+ BOOST_TEST(sl.is_loaded());
+ BOOST_TEST(sl);
+
+ boost::dll::fs::error_code ec;
+ shared_library sl2(sl, ec);
+ BOOST_TEST(!ec);
+ BOOST_TEST(sl.is_loaded());
+ BOOST_TEST(sl);
+ BOOST_TEST(sl2.is_loaded());
+ BOOST_TEST(sl2);
+ BOOST_TEST(sl2.location() == sl.location());
+
+ shared_library sl3(sl);
+ BOOST_TEST(sl.is_loaded());
+ BOOST_TEST(sl);
+ BOOST_TEST(sl3.is_loaded());
+ BOOST_TEST(sl3);
+
+ shared_library sl4;
+ sl4.assign(sl, ec);
+ BOOST_TEST(!ec);
+ BOOST_TEST(sl.is_loaded());
+ BOOST_TEST(sl);
+ BOOST_TEST(sl4.is_loaded());
+ BOOST_TEST(sl4);
+ }
+
+ { // Non-default flags with assignment and error_code
+ boost::dll::fs::error_code ec;
+ shared_library sl(shared_library_path, load_mode::rtld_lazy | load_mode::rtld_global, ec);
+ BOOST_TEST(sl.is_loaded());
+ BOOST_TEST(sl);
+ BOOST_TEST(!ec);
+ BOOST_TEST(lib_path_equal(sl.location(), shared_library_path));
+
+ shared_library sl2(sl, ec);
+ BOOST_TEST(!ec);
+ BOOST_TEST(sl.is_loaded());
+ BOOST_TEST(sl);
+ BOOST_TEST(sl2.is_loaded());
+ BOOST_TEST(sl2);
+ BOOST_TEST(sl2.location() == sl.location());
+
+ shared_library sl3(sl);
+ BOOST_TEST(sl.is_loaded());
+ BOOST_TEST(sl);
+ BOOST_TEST(sl3.is_loaded());
+ BOOST_TEST(sl3);
+ BOOST_TEST(sl3.location() == sl.location());
+ }
+
+ { // self_load
+ shared_library sl(program_location());
+ BOOST_TEST(sl.is_loaded());
+ BOOST_TEST(sl);
+ std::cout << "\nProgram location: " << program_location();
+ std::cout << "\nLibrary location: " << sl.location();
+ BOOST_TEST( boost::dll::fs::equivalent(sl.location(), program_location()) );
+
+ boost::dll::fs::error_code ec;
+ shared_library sl2(program_location());
+ BOOST_TEST(sl2.is_loaded());
+ BOOST_TEST( boost::dll::fs::equivalent(sl2.location(), program_location()) );
+ BOOST_TEST(sl2);
+ BOOST_TEST(!ec);
+
+ BOOST_TEST(sl == sl2);
+ BOOST_TEST(!(sl < sl2 || sl2 <sl));
+ BOOST_TEST(!(sl != sl2));
+
+ sl.load(shared_library_path);
+ BOOST_TEST(sl != sl2);
+ BOOST_TEST(sl < sl2 || sl2 <sl);
+ BOOST_TEST(!(sl == sl2));
+
+ sl.unload();
+ BOOST_TEST(!sl);
+ BOOST_TEST(sl != sl2);
+ BOOST_TEST(sl < sl2 || sl2 <sl);
+ BOOST_TEST(!(sl == sl2));
+
+ sl2.unload();
+ BOOST_TEST(!sl2);
+ BOOST_TEST(sl == sl2);
+ BOOST_TEST(!(sl < sl2 || sl2 <sl));
+ BOOST_TEST(!(sl != sl2));
+
+ // assigning self
+ sl.load(program_location());
+ sl2 = sl;
+ BOOST_TEST(sl == sl2);
+ BOOST_TEST(sl.location() == sl2.location());
+ }
+
+ {
+ shared_library sl;
+ boost::dll::fs::error_code ec;
+ sl.load(shared_library_path, load_mode::rtld_lazy | load_mode::rtld_global, ec);
+ BOOST_TEST(sl.is_loaded());
+ BOOST_TEST(sl);
+ BOOST_TEST(!ec);
+ BOOST_TEST(lib_path_equal(sl.location(), shared_library_path));
+
+ sl.load(program_location());
+ BOOST_TEST(sl.is_loaded());
+ BOOST_TEST(sl);
+
+ sl.load(program_location());
+ BOOST_TEST(sl.is_loaded());
+ BOOST_TEST(sl);
+ BOOST_TEST(!ec);
+ }
+
+ { // self_load
+ shared_library sl;
+ boost::dll::fs::error_code ec;
+ sl.load(program_location());
+ BOOST_TEST(sl.is_loaded());
+ BOOST_TEST(sl);
+ BOOST_TEST(!ec);
+ }
+
+ { // unload
+ shared_library sl(shared_library_path);
+ BOOST_TEST(sl.is_loaded());
+ BOOST_TEST(sl);
+ BOOST_TEST(lib_path_equal(sl.location(), shared_library_path));
+ sl.unload();
+ BOOST_TEST(!sl.is_loaded());
+ BOOST_TEST(!sl);
+ }
+
+
+ { // error_code load calls test
+ boost::dll::fs::error_code ec;
+ 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);
+ shared_library starts_with_lib(
+ boost::dll::fs::path(guard.actual_path_).replace_extension(),
+ load_mode::append_decorations
+ );
+
+ starts_with_lib.load(
+ boost::dll::fs::path(guard.actual_path_).replace_extension(),
+ load_mode::append_decorations
+ );
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/dll/test/shared_library_search_symbol_test.cpp b/src/boost/libs/dll/test/shared_library_search_symbol_test.cpp
new file mode 100644
index 000000000..cf1dc66fc
--- /dev/null
+++ b/src/boost/libs/dll/test/shared_library_search_symbol_test.cpp
@@ -0,0 +1,49 @@
+// Copyright 2011-2012 Renato Tegon Forti
+// Copyright 2014 Renato Tegon Forti, Antony Polukhin.
+// Copyright 2015-2019 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 "../example/b2_workarounds.hpp"
+#include <boost/dll.hpp>
+#include <boost/core/lightweight_test.hpp>
+
+// Unit Tests
+
+extern "C" void BOOST_SYMBOL_EXPORT exef() {
+}
+
+int main(int argc, char* argv[])
+{
+ using namespace boost::dll;
+
+ boost::dll::fs::path shared_library_path = b2_workarounds::first_lib_from_argv(argc, argv);
+ BOOST_TEST(shared_library_path.string().find("test_library") != std::string::npos);
+ BOOST_TEST(b2_workarounds::is_shared_library(shared_library_path));
+ std::cout << "Library: " << shared_library_path;
+
+ {
+ shared_library sl(shared_library_path);
+ BOOST_TEST(sl.has("say_hello"));
+ BOOST_TEST(sl.has("lib_version"));
+ BOOST_TEST(sl.has("integer_g"));
+ BOOST_TEST(sl.has(std::string("integer_g")));
+ BOOST_TEST(!sl.has("i_do_not_exist"));
+ BOOST_TEST(!sl.has(std::string("i_do_not_exist")));
+ }
+
+ {
+ shared_library sl(program_location());
+ BOOST_TEST(sl.has("exef"));
+ BOOST_TEST(!sl.has("i_do_not_exist"));
+ }
+
+
+ exef(); // Make sure that this function still callable in traditional way
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/dll/test/structures_tests.cpp b/src/boost/libs/dll/test/structures_tests.cpp
new file mode 100644
index 000000000..1598dc735
--- /dev/null
+++ b/src/boost/libs/dll/test/structures_tests.cpp
@@ -0,0 +1,345 @@
+// Copyright 2014 Renato Tegon Forti, Antony Polukhin.
+// Copyright 2015-2019 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/dll/detail/elf_info.hpp>
+#include <boost/dll/detail/pe_info.hpp>
+#include <boost/dll/detail/macho_info.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/core/lightweight_test.hpp>
+#include <boost/predef/os.h>
+
+#if BOOST_OS_WINDOWS
+# include <windows.h>
+#elif BOOST_OS_MACOS || BOOST_OS_IOS
+# include <mach-o/loader.h>
+# include <mach-o/nlist.h>
+#elif BOOST_OS_QNX
+// QNX's copy of <elf.h> and <link.h> reside in sys folder
+# include <sys/elf.h>
+#else
+ #include <elf.h>
+#endif
+
+namespace dd = boost::dll::detail;
+
+template <class T1, class T2>
+inline std::size_t get_offset(const T1& v1, const T2& v2) {
+ const unsigned char* p1 = reinterpret_cast<const unsigned char*>(&v1);
+ const unsigned char* p2 = reinterpret_cast<const unsigned char*>(&v2);
+
+ if (p1 < p2) {
+ return static_cast<std::size_t>(p2 - p1);
+ }
+
+ return static_cast<std::size_t>(p1 - p2);
+}
+
+#define CHECK_FIELD(Field) \
+ BOOST_STATIC_ASSERT(sizeof(v1.Field) == sizeof(v2.Field)); \
+ BOOST_TEST(get_offset(v1, v1.Field) == get_offset(v2, v2.Field)) \
+ /**/
+
+
+// ELF structures
+template <class T1, class T2>
+void elf_header_checks(const T1& v1, const T2& v2) {
+ BOOST_STATIC_ASSERT(sizeof(T1) == sizeof(T2));
+
+ CHECK_FIELD(e_ident);
+ CHECK_FIELD(e_type);
+ CHECK_FIELD(e_machine);
+ CHECK_FIELD(e_version);
+ CHECK_FIELD(e_entry);
+ CHECK_FIELD(e_phoff);
+ CHECK_FIELD(e_shoff);
+ CHECK_FIELD(e_flags);
+ CHECK_FIELD(e_ehsize);
+ CHECK_FIELD(e_phentsize);
+ CHECK_FIELD(e_phnum);
+ CHECK_FIELD(e_shentsize);
+ CHECK_FIELD(e_shnum);
+ CHECK_FIELD(e_shstrndx);
+}
+
+template <class T1, class T2>
+void elf_sheader_checks(const T1& v1, const T2& v2) {
+ BOOST_STATIC_ASSERT(sizeof(T1) == sizeof(T2));
+
+ CHECK_FIELD(sh_name);
+ CHECK_FIELD(sh_type);
+ CHECK_FIELD(sh_flags);
+ CHECK_FIELD(sh_addr);
+ CHECK_FIELD(sh_offset);
+ CHECK_FIELD(sh_size);
+ CHECK_FIELD(sh_link);
+ CHECK_FIELD(sh_info);
+ CHECK_FIELD(sh_addralign);
+ CHECK_FIELD(sh_entsize);
+}
+
+template <class T1, class T2>
+void elf_sym_header_checks(const T1& v1, const T2& v2) {
+ BOOST_STATIC_ASSERT(sizeof(T1) == sizeof(T2));
+
+ CHECK_FIELD(st_name);
+ CHECK_FIELD(st_value);
+ CHECK_FIELD(st_size);
+ CHECK_FIELD(st_info);
+ CHECK_FIELD(st_other);
+ CHECK_FIELD(st_shndx);
+}
+
+
+// PE structures
+template <class T>
+void generic_header_check(const T& v1, const dd::IMAGE_DOS_HEADER_& v2) {
+ BOOST_STATIC_ASSERT(sizeof(v1) == sizeof(v2));
+
+ CHECK_FIELD(e_magic);
+ CHECK_FIELD(e_cblp);
+ CHECK_FIELD(e_cp);
+ CHECK_FIELD(e_crlc);
+ CHECK_FIELD(e_cparhdr);
+ CHECK_FIELD(e_minalloc);
+ CHECK_FIELD(e_maxalloc);
+ CHECK_FIELD(e_ss);
+ CHECK_FIELD(e_sp);
+ CHECK_FIELD(e_csum);
+ CHECK_FIELD(e_ip);
+ CHECK_FIELD(e_cs);
+ CHECK_FIELD(e_lfarlc);
+ CHECK_FIELD(e_ovno);
+ CHECK_FIELD(e_res);
+ CHECK_FIELD(e_oemid);
+ CHECK_FIELD(e_oeminfo);
+ CHECK_FIELD(e_res2);
+ CHECK_FIELD(e_lfanew);
+}
+
+template <class T>
+void generic_header_check(const T& v1, const dd::IMAGE_FILE_HEADER_& v2) {
+ BOOST_STATIC_ASSERT(sizeof(v1) == sizeof(v2));
+
+ CHECK_FIELD(Machine);
+ CHECK_FIELD(NumberOfSections);
+ CHECK_FIELD(TimeDateStamp);
+ CHECK_FIELD(PointerToSymbolTable);
+ CHECK_FIELD(NumberOfSymbols);
+ CHECK_FIELD(SizeOfOptionalHeader);
+ CHECK_FIELD(Characteristics);
+}
+
+template <class T>
+void generic_header_check(const T& v1, const dd::IMAGE_DATA_DIRECTORY_& v2) {
+ BOOST_STATIC_ASSERT(sizeof(v1) == sizeof(v2));
+
+ CHECK_FIELD(VirtualAddress);
+ CHECK_FIELD(Size);
+}
+
+template <class T>
+void generic_header_check(const T& v1, const dd::IMAGE_EXPORT_DIRECTORY_& v2) {
+ BOOST_STATIC_ASSERT(sizeof(v1) == sizeof(v2));
+
+ CHECK_FIELD(Characteristics);
+ CHECK_FIELD(TimeDateStamp);
+ CHECK_FIELD(MajorVersion);
+ CHECK_FIELD(MinorVersion);
+ CHECK_FIELD(Name);
+ CHECK_FIELD(Base);
+ CHECK_FIELD(NumberOfFunctions);
+ CHECK_FIELD(NumberOfNames);
+ CHECK_FIELD(AddressOfFunctions);
+ CHECK_FIELD(AddressOfNames);
+ CHECK_FIELD(AddressOfNameOrdinals);
+}
+
+
+template <class T>
+void generic_header_check(const T& v1, const dd::IMAGE_SECTION_HEADER_& v2) {
+ BOOST_STATIC_ASSERT(sizeof(v1) == sizeof(v2));
+
+ CHECK_FIELD(Name);
+ CHECK_FIELD(VirtualAddress);
+ CHECK_FIELD(SizeOfRawData);
+ CHECK_FIELD(PointerToRawData);
+ CHECK_FIELD(PointerToRelocations);
+ CHECK_FIELD(PointerToLinenumbers);
+ CHECK_FIELD(NumberOfRelocations);
+ CHECK_FIELD(NumberOfLinenumbers);
+ CHECK_FIELD(Characteristics);
+}
+
+template <class T, class AddrT>
+void generic_header_check(const T& v1, const dd::IMAGE_OPTIONAL_HEADER_template<AddrT>& v2) {
+ BOOST_STATIC_ASSERT(sizeof(v1) == sizeof(v2));
+
+ CHECK_FIELD(Magic);
+ CHECK_FIELD(MajorLinkerVersion);
+ CHECK_FIELD(MinorLinkerVersion);
+ CHECK_FIELD(SizeOfCode);
+ CHECK_FIELD(SizeOfInitializedData);
+ CHECK_FIELD(SizeOfUninitializedData);
+ CHECK_FIELD(AddressOfEntryPoint);
+ CHECK_FIELD(ImageBase);
+ CHECK_FIELD(SectionAlignment);
+ CHECK_FIELD(FileAlignment);
+ CHECK_FIELD(MajorOperatingSystemVersion);
+ CHECK_FIELD(MinorOperatingSystemVersion);
+ CHECK_FIELD(MajorImageVersion);
+ CHECK_FIELD(MinorImageVersion);
+ CHECK_FIELD(MajorSubsystemVersion);
+ CHECK_FIELD(MinorSubsystemVersion);
+ CHECK_FIELD(Win32VersionValue);
+ CHECK_FIELD(SizeOfImage);
+ CHECK_FIELD(SizeOfHeaders);
+ CHECK_FIELD(CheckSum);
+ CHECK_FIELD(Subsystem);
+ CHECK_FIELD(DllCharacteristics);
+ CHECK_FIELD(SizeOfStackReserve);
+ CHECK_FIELD(SizeOfStackCommit);
+ CHECK_FIELD(SizeOfHeapReserve);
+ CHECK_FIELD(SizeOfHeapCommit);
+ CHECK_FIELD(LoaderFlags);
+ CHECK_FIELD(NumberOfRvaAndSizes);
+ CHECK_FIELD(DataDirectory);
+}
+
+template <class T, class AddrT>
+void generic_header_check(const T& v1, const dd::IMAGE_NT_HEADERS_template<AddrT>& v2) {
+ BOOST_STATIC_ASSERT(sizeof(v1) == sizeof(v2));
+
+ CHECK_FIELD(Signature);
+ CHECK_FIELD(FileHeader);
+ CHECK_FIELD(OptionalHeader);
+}
+template <class T, class AddrT>
+void generic_header_check(const T& v1, const dd::mach_header_template<AddrT>& v2) {
+ BOOST_STATIC_ASSERT(sizeof(v1) == sizeof(v2));
+
+ CHECK_FIELD(magic);
+ CHECK_FIELD(cputype);
+ CHECK_FIELD(cpusubtype);
+ CHECK_FIELD(filetype);
+ CHECK_FIELD(ncmds);
+ CHECK_FIELD(sizeofcmds);
+ //CHECK_FIELD(flags);
+}
+
+template <class T, class AddrT>
+void generic_header_check(const T& v1, const dd::segment_command_template<AddrT>& v2) {
+ BOOST_STATIC_ASSERT(sizeof(v1) == sizeof(v2));
+
+ CHECK_FIELD(cmd);
+ CHECK_FIELD(cmdsize);
+ CHECK_FIELD(segname);
+ CHECK_FIELD(vmaddr);
+ CHECK_FIELD(vmsize);
+ CHECK_FIELD(fileoff);
+ CHECK_FIELD(filesize);
+ CHECK_FIELD(maxprot);
+ CHECK_FIELD(initprot);
+ CHECK_FIELD(nsects);
+ CHECK_FIELD(flags);
+}
+
+template <class T, class AddrT>
+void generic_header_check(const T& v1, const dd::section_template<AddrT>& v2) {
+ BOOST_STATIC_ASSERT(sizeof(v1) == sizeof(v2));
+
+ CHECK_FIELD(sectname);
+ CHECK_FIELD(segname);
+ CHECK_FIELD(addr);
+ CHECK_FIELD(size);
+ CHECK_FIELD(offset);
+ CHECK_FIELD(align);
+ CHECK_FIELD(reloff);
+ CHECK_FIELD(nreloc);
+ CHECK_FIELD(flags);
+ //CHECK_FIELD(reserved vs reserveed1&reserved2);
+}
+
+template <class T>
+void generic_header_check(const T& v1, const dd::symtab_command_& v2) {
+ BOOST_STATIC_ASSERT(sizeof(v1) == sizeof(v2));
+
+ CHECK_FIELD(cmd);
+ CHECK_FIELD(cmdsize);
+ CHECK_FIELD(symoff);
+ CHECK_FIELD(nsyms);
+ CHECK_FIELD(stroff);
+ CHECK_FIELD(strsize);
+}
+
+template <class T, class AddrT>
+void generic_header_check(const T& v1, const dd::nlist_template<AddrT>& v2) {
+ BOOST_STATIC_ASSERT(sizeof(v1) == sizeof(v2));
+
+ //CHECK_FIELD(n_strx);
+ CHECK_FIELD(n_type);
+ CHECK_FIELD(n_sect);
+ CHECK_FIELD(n_desc);
+ CHECK_FIELD(n_value);
+}
+
+template <class T>
+void generic_header_check(const T& v1, const dd::load_command_& v2) {
+ BOOST_STATIC_ASSERT(sizeof(v1) == sizeof(v2));
+
+ CHECK_FIELD(cmd);
+ CHECK_FIELD(cmdsize);
+}
+
+
+
+// Unit Tests
+int main(int /*argc*/, char* /*argv*/[]) {
+
+#if BOOST_OS_WINDOWS
+ generic_header_check(::IMAGE_DOS_HEADER(), dd::IMAGE_DOS_HEADER_());
+ generic_header_check(::IMAGE_FILE_HEADER(), dd::IMAGE_FILE_HEADER_());
+ generic_header_check(::IMAGE_DATA_DIRECTORY(), dd::IMAGE_DATA_DIRECTORY_());
+ generic_header_check(::IMAGE_EXPORT_DIRECTORY(), dd::IMAGE_EXPORT_DIRECTORY_());
+ generic_header_check(::IMAGE_SECTION_HEADER(), dd::IMAGE_SECTION_HEADER_());
+ generic_header_check(::IMAGE_OPTIONAL_HEADER32(), dd::IMAGE_OPTIONAL_HEADER32_());
+ generic_header_check(::IMAGE_OPTIONAL_HEADER64(), dd::IMAGE_OPTIONAL_HEADER64_());
+ generic_header_check(::IMAGE_NT_HEADERS32(), dd::IMAGE_NT_HEADERS32_());
+ generic_header_check(::IMAGE_NT_HEADERS64(), dd::IMAGE_NT_HEADERS64_());
+#elif BOOST_OS_MACOS || BOOST_OS_IOS
+ generic_header_check(::mach_header(), dd::mach_header_32_());
+ generic_header_check(::mach_header_64(), dd::mach_header_64_());
+
+ generic_header_check(::segment_command(), dd::segment_command_32_());
+ generic_header_check(::segment_command_64(), dd::segment_command_64_());
+
+ generic_header_check(::section(), dd::section_32_());
+ generic_header_check(::section_64(), dd::section_64_());
+
+ generic_header_check(::load_command(), dd::load_command_());
+ generic_header_check(::symtab_command(), dd::symtab_command_());
+
+ struct ::nlist nl32_var;
+ generic_header_check(nl32_var, dd::nlist_32_());
+ struct ::nlist_64 nl64_var;
+ generic_header_check(nl64_var, dd::nlist_64_());
+
+#else
+ elf_header_checks(::Elf32_Ehdr(), dd::Elf32_Ehdr_());
+ elf_header_checks(::Elf64_Ehdr(), dd::Elf64_Ehdr_());
+
+ elf_sheader_checks(::Elf32_Shdr(), dd::Elf32_Shdr_());
+ elf_sheader_checks(::Elf64_Shdr(), dd::Elf64_Shdr_());
+
+ elf_sym_header_checks(::Elf32_Sym(), dd::Elf32_Sym_());
+ elf_sym_header_checks(::Elf64_Sym(), dd::Elf64_Sym_());
+#endif
+
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/dll/test/symbol_runtime_info_test.cpp b/src/boost/libs/dll/test/symbol_runtime_info_test.cpp
new file mode 100644
index 000000000..bfeb69bf6
--- /dev/null
+++ b/src/boost/libs/dll/test/symbol_runtime_info_test.cpp
@@ -0,0 +1,231 @@
+// Copyright 2014 Renato Tegon Forti, Antony Polukhin.
+// Copyright 2015-2019 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 "../example/b2_workarounds.hpp"
+#include <boost/dll.hpp>
+#include <boost/dll/runtime_symbol_info.hpp>
+#include <boost/filesystem/operations.hpp>
+
+#include <boost/core/lightweight_test.hpp>
+
+#include <boost/predef/os.h>
+
+
+#include <cmath>
+#include <exception> // std::set_terminate
+#include <signal.h> // ::signal
+
+// Makes global error variables dirty. Useful for preventing issues like https://github.com/boostorg/dll/issues/16
+void make_error_code_dirty() {
+ using namespace std;
+ (void)log(-1.0);
+
+#if BOOST_OS_WINDOWS
+ boost::winapi::WCHAR_ path_hldr[10];
+ int some_invalid_value_for_handle = 0xFF004242;
+ boost::winapi::HMODULE_ some_invalid_handle;
+ memcpy(&some_invalid_handle, &some_invalid_value_for_handle, sizeof(some_invalid_value_for_handle));
+ boost::winapi::GetModuleFileNameW(some_invalid_handle, path_hldr, 10);
+#endif
+}
+
+
+
+// lib functions
+
+typedef float (lib_version_func)();
+typedef void (say_hello_func) ();
+typedef int (increment) (int);
+
+// exe function
+extern "C" int BOOST_SYMBOL_EXPORT exef() {
+ return 15;
+}
+
+
+extern "C" void BOOST_SYMBOL_EXPORT my_terminate_handler() {
+ std::abort();
+}
+
+extern "C" void BOOST_SYMBOL_EXPORT my_signal_handler(int) {
+ std::abort();
+}
+
+void internal_function() {}
+int internal_variable = 1;
+
+// Unit Tests
+int main(int argc, char* argv[]) {
+ using namespace boost::dll;
+
+ boost::dll::fs::path shared_library_path = b2_workarounds::first_lib_from_argv(argc, argv);
+ BOOST_TEST(shared_library_path.string().find("test_library") != std::string::npos);
+
+ make_error_code_dirty();
+
+ shared_library lib(shared_library_path);
+
+ std::cout << std::endl;
+ std::cout << "shared_library: " << shared_library_path << std::endl;
+ std::cout << "symbol_location: " << symbol_location(lib.get<int>("integer_g")) << std::endl;
+ std::cout << "lib.location(): " << lib.location() << std::endl;
+ BOOST_TEST(
+ symbol_location(lib.get<int>("integer_g")) == lib.location()
+ );
+
+ make_error_code_dirty();
+
+ BOOST_TEST(
+ symbol_location(lib.get<say_hello_func>("say_hello")) == lib.location()
+ );
+
+ BOOST_TEST(
+ symbol_location(lib.get<lib_version_func>("lib_version")) == lib.location()
+ );
+
+ make_error_code_dirty();
+
+ BOOST_TEST(
+ symbol_location(lib.get<const int>("const_integer_g")) == lib.location()
+ );
+
+ // Checking that symbols are still available, after another load+unload of the library
+ { shared_library sl2(shared_library_path); }
+
+ BOOST_TEST(
+ symbol_location(lib.get<int>("integer_g")) == lib.location()
+ );
+
+
+ make_error_code_dirty();
+
+ // Checking aliases
+ BOOST_TEST(
+ symbol_location(lib.get<std::size_t(*)(const std::vector<int>&)>("foo_bar")) == lib.location()
+ );
+ BOOST_TEST(
+ symbol_location(lib.get_alias<std::size_t(const std::vector<int>&)>("foo_bar")) == lib.location()
+ );
+
+
+ BOOST_TEST(
+ symbol_location(lib.get<std::size_t*>("foo_variable")) == lib.location()
+ );
+ BOOST_TEST(
+ symbol_location(lib.get_alias<std::size_t>("foo_variable")) == lib.location()
+ );
+
+ { // self
+
+ make_error_code_dirty();
+
+ shared_library sl(program_location());
+
+ make_error_code_dirty();
+
+ BOOST_TEST(
+ (boost::dll::fs::equivalent(symbol_location(sl.get<int(void)>("exef")), argv[0]))
+ );
+ }
+
+ { // self with error_code
+ boost::dll::fs::error_code ec;
+ shared_library sl(program_location(ec));
+ BOOST_TEST(!ec);
+
+ BOOST_TEST(
+ (boost::dll::fs::equivalent(symbol_location(sl.get<int(void)>("exef"), ec), argv[0]))
+ );
+ BOOST_TEST(!ec);
+
+ symbol_location(&sl.get<int(void)>("exef"), ec);
+ BOOST_TEST(ec);
+ }
+
+ std::cout << "\ninternal_function: " << symbol_location(internal_function);
+ std::cout << "\nargv[0] : " << boost::filesystem::absolute(argv[0]);
+ BOOST_TEST(
+ (boost::dll::fs::equivalent(symbol_location(internal_function), argv[0]))
+ );
+
+ BOOST_TEST(
+ (boost::dll::fs::equivalent(symbol_location(internal_variable), argv[0]))
+ );
+
+ make_error_code_dirty();
+
+ BOOST_TEST(
+ (boost::dll::fs::equivalent(this_line_location(), argv[0]))
+ );
+
+ { // this_line_location with error_code
+ boost::dll::fs::error_code ec;
+ make_error_code_dirty();
+ BOOST_TEST(
+ (boost::dll::fs::equivalent(this_line_location(ec), argv[0]))
+ );
+ BOOST_TEST(!ec);
+ }
+
+ BOOST_TEST(
+ lib.get_alias<boost::dll::fs::path()>("module_location_from_itself")() == lib.location()
+ );
+
+ // Checking docs content
+ std::cout << "\nsymbol_location(std::cerr); // " << symbol_location(std::cerr);
+ std::cout << "\nsymbol_location(std::puts); // " << symbol_location(std::puts);
+
+ std::set_terminate(&my_terminate_handler);
+ BOOST_TEST((boost::dll::fs::equivalent(
+ symbol_location_ptr(std::set_terminate(0)),
+ argv[0]
+ )));
+
+ {
+ boost::dll::fs::error_code ec;
+ boost::dll::fs::path p = symbol_location_ptr(std::set_terminate(0), ec);
+ BOOST_TEST(ec || !p.empty());
+ }
+
+ {
+ boost::dll::fs::error_code ec;
+ symbol_location(std::set_terminate(0), ec),
+ BOOST_TEST(ec);
+ }
+
+ {
+ std::set_terminate(&my_terminate_handler);
+ boost::dll::fs::error_code ec;
+ make_error_code_dirty();
+ symbol_location(std::set_terminate(0), ec),
+ BOOST_TEST(ec);
+ }
+
+ {
+ boost::dll::fs::error_code ec;
+ ::signal(SIGSEGV, &my_signal_handler);
+ boost::dll::fs::path p = symbol_location_ptr(::signal(SIGSEGV, SIG_DFL), ec);
+ BOOST_TEST((boost::dll::fs::equivalent(
+ p,
+ argv[0]
+ )) || ec);
+ }
+
+ {
+ ::signal(SIGSEGV, &my_signal_handler);
+ boost::dll::fs::error_code ec;
+ make_error_code_dirty();
+ symbol_location(::signal(SIGSEGV, SIG_DFL), ec);
+ BOOST_TEST(ec);
+ }
+
+
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/dll/test/template_method_linux_test.cpp b/src/boost/libs/dll/test/template_method_linux_test.cpp
new file mode 100644
index 000000000..cb4969609
--- /dev/null
+++ b/src/boost/libs/dll/test/template_method_linux_test.cpp
@@ -0,0 +1,67 @@
+// Copyright 2019 Ramil Gauss.
+// Copyright 2019 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)
+
+#include <boost/predef.h>
+#if (__cplusplus >= 201402L) || (BOOST_COMP_MSVC >= BOOST_VERSION_NUMBER(14,0,0))
+
+#include <boost/dll/smart_library.hpp>
+#include <boost/dll/import_mangled.hpp>
+#include <boost/dll/import_class.hpp>
+
+#include <iostream>
+#include <string>
+
+#include "../example/b2_workarounds.hpp"
+#include <boost/core/lightweight_test.hpp>
+
+
+namespace space {
+ class BOOST_SYMBOL_EXPORT my_plugin {
+ public:
+ template <typename Arg>
+ BOOST_SYMBOL_EXPORT int Func(); // defined in cpp_test_library.cpp
+ };
+}
+
+int main(int argc, char** argv) {
+ unsigned matches_found = 0;
+ boost::dll::fs::path lib_path = b2_workarounds::first_lib_from_argv(argc, argv);
+ boost::dll::experimental::smart_library lib(lib_path);
+
+ auto storage = lib.symbol_storage().get_storage();
+ for (auto& s : storage) {
+ auto& demangled = s.demangled;
+ BOOST_TEST(demangled.data());
+
+ auto beginFound = demangled.find("Func<");
+ if (beginFound == std::string::npos)
+ continue;
+
+ auto endFound = demangled.find("(");
+ if (endFound == std::string::npos)
+ continue;
+
+ // Usually "Func<space::my_plugin>" on Linux, "Func<class space::my_plugin>" on Windows.
+ auto funcName = demangled.substr(beginFound, endFound - beginFound);
+ std::cout << "Function name: " << funcName.data() << std::endl;
+ auto typeIndexFunc = boost::dll::experimental::import_mangled<space::my_plugin, int()>(lib, funcName);
+
+ space::my_plugin cl;
+ BOOST_TEST_EQ(typeIndexFunc(&cl), 42);
+
+ ++matches_found;
+ break;
+ }
+ BOOST_TEST_EQ(matches_found, 1);
+
+ return boost::report_errors();
+}
+
+
+#else
+int main() {}
+#endif
diff --git a/src/boost/libs/dll/test/test_library.cpp b/src/boost/libs/dll/test/test_library.cpp
new file mode 100644
index 000000000..fee07c629
--- /dev/null
+++ b/src/boost/libs/dll/test/test_library.cpp
@@ -0,0 +1,115 @@
+// Copyright 2011-2012 Renato Tegon Forti
+// Copyright 2014 Renato Tegon Forti, Antony Polukhin.
+// Copyright 2015-2019 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
+
+// MinGW related workaround
+#define BOOST_DLL_FORCE_ALIAS_INSTANTIATION
+
+#include <boost/dll/config.hpp>
+#include <boost/dll/alias.hpp>
+#include <iostream>
+#include <vector>
+
+#include <boost/shared_ptr.hpp>
+#include <boost/make_shared.hpp>
+#include <boost/fusion/container.hpp>
+
+#define LIBRARY_API BOOST_SYMBOL_EXPORT
+
+extern "C" void LIBRARY_API say_hello(void);
+extern "C" float LIBRARY_API lib_version(void);
+extern "C" int LIBRARY_API increment(int);
+
+extern "C" int LIBRARY_API integer_g;
+extern "C" const int LIBRARY_API const_integer_g = 777;
+
+namespace foo {
+ std::size_t bar(const std::vector<int>& v) {
+ return v.size();
+ }
+
+ std::size_t variable = 42;
+}
+
+
+
+// Make sure that aliases have no problems with memory allocations and different types of input parameters
+namespace namespace1 { namespace namespace2 { namespace namespace3 {
+ typedef
+ boost::fusion::vector<std::vector<int>, std::vector<int>, std::vector<int>, const std::vector<int>*, std::vector<int>* >
+ do_share_res_t;
+
+ boost::shared_ptr<do_share_res_t> do_share(
+ std::vector<int> v1,
+ std::vector<int>& v2,
+ const std::vector<int>& v3,
+ const std::vector<int>* v4,
+ std::vector<int>* v5
+ )
+ {
+ v2.back() = 777;
+ v5->back() = 9990;
+ return boost::make_shared<do_share_res_t>(v1, v2, v3, v4, v5);
+ }
+
+ std::string info("I am a std::string from the test_library (Think of me as of 'Hello world'. Long 'Hello world').");
+
+ int& ref_returning_function() {
+ static int i = 0;
+ return i;
+ }
+}}}
+
+
+
+BOOST_DLL_ALIAS(foo::bar, foo_bar)
+BOOST_DLL_ALIAS(foo::variable, foo_variable)
+BOOST_DLL_ALIAS(namespace1::namespace2::namespace3::do_share, do_share)
+BOOST_DLL_ALIAS(namespace1::namespace2::namespace3::info, info)
+BOOST_DLL_ALIAS(const_integer_g, const_integer_g_alias)
+BOOST_DLL_ALIAS(namespace1::namespace2::namespace3::ref_returning_function, ref_returning_function)
+
+
+
+int integer_g = 100;
+
+void say_hello(void)
+{
+ std::cout << "Hello, Boost.Application!" << std::endl;
+}
+
+float lib_version(void)
+{
+ return 1.0;
+}
+
+int increment(int n)
+{
+ return ++n;
+}
+
+#include <boost/dll/runtime_symbol_info.hpp>
+
+boost::dll::fs::path this_module_location_from_itself() {
+ return boost::dll::this_line_location();
+}
+
+BOOST_DLL_ALIAS(this_module_location_from_itself, module_location_from_itself)
+
+
+
+int internal_integer_i = 0xFF0000;
+extern "C" LIBRARY_API int& reference_to_internal_integer;
+int& reference_to_internal_integer = internal_integer_i;
+
+#ifndef BOOST_NO_RVALUE_REFERENCES
+extern "C" LIBRARY_API int&& rvalue_reference_to_internal_integer;
+int&& rvalue_reference_to_internal_integer = static_cast<int&&>(internal_integer_i);
+#endif
+