diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-27 18:24:20 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-27 18:24:20 +0000 |
commit | 483eb2f56657e8e7f419ab1a4fab8dce9ade8609 (patch) | |
tree | e5d88d25d870d5dedacb6bbdbe2a966086a0a5cf /src/boost/libs/dll/example | |
parent | Initial commit. (diff) | |
download | ceph-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')
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 + |