From 483eb2f56657e8e7f419ab1a4fab8dce9ade8609 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sat, 27 Apr 2024 20:24:20 +0200 Subject: Adding upstream version 14.2.21. Signed-off-by: Daniel Baumann --- src/boost/libs/dll/example/b2_workarounds.hpp | 109 +++++++++++++++ src/boost/libs/dll/example/getting_started.cpp | 83 ++++++++++++ .../libs/dll/example/getting_started_library.cpp | 70 ++++++++++ .../libs/dll/example/mangled/import_class.cpp | 47 +++++++ .../libs/dll/example/mangled/my_cpp_plugin.hpp | 43 ++++++ src/boost/libs/dll/example/mangled/smart_lib.cpp | 58 ++++++++ .../libs/dll/example/tutorial1/my_plugin_sum.cpp | 43 ++++++ src/boost/libs/dll/example/tutorial1/tutorial1.cpp | 31 +++++ .../dll/example/tutorial2/my_plugin_aggregator.cpp | 52 ++++++++ src/boost/libs/dll/example/tutorial2/tutorial2.cpp | 36 +++++ src/boost/libs/dll/example/tutorial3/tutorial3.cpp | 56 ++++++++ src/boost/libs/dll/example/tutorial4/load_self.cpp | 39 ++++++ .../libs/dll/example/tutorial4/static_plugin.cpp | 42 ++++++ .../libs/dll/example/tutorial4/static_plugin.hpp | 22 ++++ src/boost/libs/dll/example/tutorial5/load_all.cpp | 146 +++++++++++++++++++++ .../libs/dll/example/tutorial6/on_unload_lib.cpp | 48 +++++++ src/boost/libs/dll/example/tutorial6/tutorial6.cpp | 39 ++++++ src/boost/libs/dll/example/tutorial7/library1.cpp | 21 +++ src/boost/libs/dll/example/tutorial7/library2.cpp | 26 ++++ src/boost/libs/dll/example/tutorial7/tutorial7.cpp | 48 +++++++ .../libs/dll/example/tutorial8/refcounting_api.hpp | 77 +++++++++++ .../dll/example/tutorial8/refcounting_plugin.cpp | 47 +++++++ .../dll/example/tutorial8/refcounting_plugin.hpp | 17 +++ src/boost/libs/dll/example/tutorial8/tutorial8.cpp | 25 ++++ .../dll/example/tutorial8/tutorial8_static.cpp | 23 ++++ src/boost/libs/dll/example/tutorial9/tutorial9.cpp | 60 +++++++++ .../dll/example/tutorial_common/my_plugin_api.hpp | 24 ++++ 27 files changed, 1332 insertions(+) create mode 100644 src/boost/libs/dll/example/b2_workarounds.hpp create mode 100644 src/boost/libs/dll/example/getting_started.cpp create mode 100644 src/boost/libs/dll/example/getting_started_library.cpp create mode 100644 src/boost/libs/dll/example/mangled/import_class.cpp create mode 100644 src/boost/libs/dll/example/mangled/my_cpp_plugin.hpp create mode 100644 src/boost/libs/dll/example/mangled/smart_lib.cpp create mode 100644 src/boost/libs/dll/example/tutorial1/my_plugin_sum.cpp create mode 100644 src/boost/libs/dll/example/tutorial1/tutorial1.cpp create mode 100644 src/boost/libs/dll/example/tutorial2/my_plugin_aggregator.cpp create mode 100644 src/boost/libs/dll/example/tutorial2/tutorial2.cpp create mode 100644 src/boost/libs/dll/example/tutorial3/tutorial3.cpp create mode 100644 src/boost/libs/dll/example/tutorial4/load_self.cpp create mode 100644 src/boost/libs/dll/example/tutorial4/static_plugin.cpp create mode 100644 src/boost/libs/dll/example/tutorial4/static_plugin.hpp create mode 100644 src/boost/libs/dll/example/tutorial5/load_all.cpp create mode 100644 src/boost/libs/dll/example/tutorial6/on_unload_lib.cpp create mode 100644 src/boost/libs/dll/example/tutorial6/tutorial6.cpp create mode 100644 src/boost/libs/dll/example/tutorial7/library1.cpp create mode 100644 src/boost/libs/dll/example/tutorial7/library2.cpp create mode 100644 src/boost/libs/dll/example/tutorial7/tutorial7.cpp create mode 100644 src/boost/libs/dll/example/tutorial8/refcounting_api.hpp create mode 100644 src/boost/libs/dll/example/tutorial8/refcounting_plugin.cpp create mode 100644 src/boost/libs/dll/example/tutorial8/refcounting_plugin.hpp create mode 100644 src/boost/libs/dll/example/tutorial8/tutorial8.cpp create mode 100644 src/boost/libs/dll/example/tutorial8/tutorial8_static.cpp create mode 100644 src/boost/libs/dll/example/tutorial9/tutorial9.cpp create mode 100644 src/boost/libs/dll/example/tutorial_common/my_plugin_api.hpp (limited to 'src/boost/libs/dll/example') 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 +#include +#include +#include +#include + +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(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 +#include +#include +#include +#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 c_func = dll::import( + 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 c_var = dll::import( + 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 /*->*/ /*=auto*/ cpp_func = dll::import_alias( + 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( + 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 cpp_var = dll::import( + 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 +#include + +#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(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 +#include +#include + + + +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("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(lib, "space::my_plugin::value"); +//] +//[import_class_ctor + auto cl = import_class(lib, "space::my_plugin::some_class", size, "MyName"); +//] +//[import_class_name + auto name = import_mangled(lib, "name"); + std::cout << "Name: " << (cl->*name)() << std::endl; +//] +//[import_class_calc + auto calc = import_mangled(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 + +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 // for import_alias +#include +#include + +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("space::my_plugin::size"); //get the size function + + auto size = size_f(); // get the size of the class + std::unique_ptr buffer(new char[size]); //allocate a buffer for the import + alias & inst = *reinterpret_cast(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(); //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("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("calculate"); + auto calc_i = lib.get_mem_fn ("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("space::my_plugin::value"); + cout << "value " << var << endl; +//] +//[smart_lib_dtor + auto dtor = lib.get_destructor(); //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 + + +//[plugcpp_my_plugin_sum +#include // 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 // for import_alias +#include +#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 plugin; // variable to hold a pointer to plugin variable + std::cout << "Loading the plugin" << std::endl; + + plugin = dll::import( // 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 +#include + +// MinGW related workaround +#define BOOST_DLL_FORCE_ALIAS_INSTANTIATION + +//[plugcpp_my_plugin_aggregator +#include // 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 create() { + return boost::shared_ptr( + 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 // for import_alias +#include +#include +#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 (pluginapi_create_t)(); + boost::function creator; + + creator = boost::dll::import_alias( // 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 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 // for import_alias +#include +#include +#include +#include "../tutorial_common/my_plugin_api.hpp" + +namespace dll = boost::dll; + +std::size_t search_for_symbols(const std::vector& 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 (pluginapi_create_t)(); + boost::function creator + = dll::import_alias(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 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 // for shared_library +#include // for program_location() +#include "static_plugin.hpp" // without this headers some compilers may optimize out the `create_plugin` symbol +#include +#include + +namespace dll = boost::dll; + +int main() { + dll::shared_library self(dll::program_location()); + + std::cout << "Call function" << std::endl; + boost::function()> creator + = self.get_alias()>("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 +#include + +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 create_plugin() { + return boost::make_shared(); +} + +} // 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 // for BOOST_DLL_ALIAS +#include +#include "../tutorial_common/my_plugin_api.hpp" + +namespace my_namespace { + boost::shared_ptr 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 // for program_location() +#include +#include +#include +#include +#include + +//[plugcpp_plugins_collector_def +namespace dll = boost::dll; + +class plugins_collector { + // Name => plugin + typedef boost::container::map 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()>("create_plugin")()->name(); + } else if (lib.has("plugin")) { + plugin_name = lib.get("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 // for BOOST_DLL_ALIAS +#include +#include + +namespace my_namespace { + +struct on_unload { + typedef boost::function 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 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 +#include +#include + +typedef boost::function 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 on_unload + = boost::dll::import_alias( + 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 // for BOOST_DLL_ALIAS_SECTIONED +#include +#include + +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 // for BOOST_DLL_ALIAS_SECTIONED +#include +#include + +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 +#include "../b2_workarounds.hpp" + +//[callplugcpp_tutorial7 +#include +#include +#include + +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 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(exports[j]) // importing function + (username); // calling function + } + } +} +//] + +int main(int argc, char* argv[]) { + /*<-*/ BOOST_ASSERT(argc >= 3); /*->*/ + std::vector 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 + +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 +#include +#include + +struct library_holding_deleter { + boost::shared_ptr lib_; + + void operator()(my_refcounting_api* p) const { + delete p; + } +}; + +inline boost::shared_ptr 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 lib + = boost::make_shared(location); + + library_holding_deleter deleter; + deleter.lib_ = lib; + + return boost::shared_ptr( + plugin, deleter + ); +} +//] + +//[plugcpp_get_plugin_refcounting +#include +#include +inline boost::shared_ptr get_plugin( + boost::dll::fs::path path, const char* func_name) +{ + typedef my_refcounting_api*(func_t)(); + boost::function creator = boost::dll::import_alias( + 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 // 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 // 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 +#include "refcounting_api.hpp" + +int main(int argc, char* argv[]) { + /*<-*/ b2_workarounds::argv_to_path_guard guard(argc, argv); /*->*/ + boost::shared_ptr 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 // program_location() +#include +#include "refcounting_plugin.hpp" + +int main() { + boost::shared_ptr 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 +#if BOOST_OS_WINDOWS + +//[callplugcpp_tutorial9 +#include // for dll::import +#include // for dll::shared_library +#include +#include +#include + +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( + "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 can not compile with + // Signature template parameter that contains calling conventions, so you'll have to remove the calling convention. + boost::function 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"); + + // 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 // 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 +#include + +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 + -- cgit v1.2.3