summaryrefslogtreecommitdiffstats
path: root/src/boost/libs/dll/example
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-27 18:24:20 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-27 18:24:20 +0000
commit483eb2f56657e8e7f419ab1a4fab8dce9ade8609 (patch)
treee5d88d25d870d5dedacb6bbdbe2a966086a0a5cf /src/boost/libs/dll/example
parentInitial commit. (diff)
downloadceph-upstream.tar.xz
ceph-upstream.zip
Adding upstream version 14.2.21.upstream/14.2.21upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/boost/libs/dll/example')
-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
27 files changed, 1332 insertions, 0 deletions
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 00000000..bb9f8ae5
--- /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 00000000..4d634662
--- /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 00000000..0264fd33
--- /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 00000000..eee4a961
--- /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 00000000..3f9e9ee1
--- /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 00000000..d8cb69c6
--- /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 00000000..09b78a64
--- /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 00000000..2827a639
--- /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 00000000..4247f89b
--- /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 00000000..83addb83
--- /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 00000000..c63615ba
--- /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 00000000..176bc01d
--- /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 00000000..84a43774
--- /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 00000000..baf93ac2
--- /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 00000000..7e7b3057
--- /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 00000000..f09ede95
--- /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 00000000..87003f02
--- /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 00000000..fa48a5da
--- /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 00000000..abdd60ff
--- /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 00000000..e0186db2
--- /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 00000000..c9178110
--- /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 00000000..bb52cdfa
--- /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 00000000..990bd214
--- /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 00000000..ef169a99
--- /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 00000000..810d322f
--- /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 00000000..2f4f5efa
--- /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 00000000..d8fe8582
--- /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
+