diff options
Diffstat (limited to 'src/boost/libs/dll/example/tutorial5/load_all.cpp')
-rw-r--r-- | src/boost/libs/dll/example/tutorial5/load_all.cpp | 146 |
1 files changed, 146 insertions, 0 deletions
diff --git a/src/boost/libs/dll/example/tutorial5/load_all.cpp b/src/boost/libs/dll/example/tutorial5/load_all.cpp new file mode 100644 index 000000000..7e7b30576 --- /dev/null +++ b/src/boost/libs/dll/example/tutorial5/load_all.cpp @@ -0,0 +1,146 @@ +// Copyright 2014 Renato Tegon Forti, Antony Polukhin. +// Copyright 2015-2019 Antony Polukhin. +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt +// or copy at http://www.boost.org/LICENSE_1_0.txt) + +// MinGW related workaround +#define BOOST_DLL_FORCE_ALIAS_INSTANTIATION + +#include "../b2_workarounds.hpp" +#include "../tutorial4/static_plugin.hpp" +#include <boost/dll/runtime_symbol_info.hpp> // for program_location() +#include <boost/dll/shared_library.hpp> +#include <boost/make_shared.hpp> +#include <boost/container/map.hpp> +#include <boost/filesystem.hpp> +#include <iostream> + +//[plugcpp_plugins_collector_def +namespace dll = boost::dll; + +class plugins_collector { + // Name => plugin + typedef boost::container::map<std::string, dll::shared_library> plugins_t; + + boost::dll::fs::path plugins_directory_; + plugins_t plugins_; + + // loads all plugins in plugins_directory_ + void load_all(); + + // Gets `my_plugin_api` instance using "create_plugin" or "plugin" imports, + // stores plugin with its name in the `plugins_` map. + void insert_plugin(BOOST_RV_REF(dll::shared_library) lib); + +public: + plugins_collector(const boost::dll::fs::path& plugins_directory) + : plugins_directory_(plugins_directory) + { + load_all(); + } + + void print_plugins() const; + + std::size_t count() const; + // ... +}; +//] + + +//[plugcpp_plugins_collector_load_all +void plugins_collector::load_all() { + namespace fs = ::boost::dll::fs; + typedef fs::path::string_type string_type; + const string_type extension = dll::shared_library::suffix().native(); + + // Searching a folder for files with '.so' or '.dll' extension + fs::recursive_directory_iterator endit; + for (fs::recursive_directory_iterator it(plugins_directory_); it != endit; ++it) { + if (!fs::is_regular_file(*it)) { + continue; + } + /*<-*/ + if ( !b2_workarounds::is_shared_library((*it).path()) ) { + continue; + } + /*->*/ + // We found a file. Trying to load it + boost::dll::fs::error_code error; + dll::shared_library plugin(it->path(), error); + if (error) { + continue; + } + std::cout << "Loaded (" << plugin.native() << "):" << it->path() << '\n'; + + // Gets plugin using "create_plugin" or "plugin" function + insert_plugin(boost::move(plugin)); + } + + dll::shared_library plugin(dll::program_location()); + std::cout << "Loaded self\n"; + insert_plugin(boost::move(plugin)); +} +//] + +//[plugcpp_plugins_collector_insert_plugin +void plugins_collector::insert_plugin(BOOST_RV_REF(dll::shared_library) lib) { + std::string plugin_name; + if (lib.has("create_plugin")) { + plugin_name = lib.get_alias<boost::shared_ptr<my_plugin_api>()>("create_plugin")()->name(); + } else if (lib.has("plugin")) { + plugin_name = lib.get<my_plugin_api>("plugin").name(); + } else { + return; + } + + if (plugins_.find(plugin_name) == plugins_.cend()) { + plugins_[plugin_name] = boost::move(lib); + } +} +//] + +void plugins_collector::print_plugins() const { + plugins_t::const_iterator const end = plugins_.cend(); + for (plugins_t::const_iterator it = plugins_.cbegin(); it != end; ++it) { + std::cout << '(' << it->second.native() << "): " << it->first << '\n'; + } +} + +std::size_t plugins_collector::count() const { + return plugins_.size(); +} + + +//[plugcpp_load_all +int main(int argc, char* argv[]) { + /*<-*/ + BOOST_ASSERT(argc >= 3); + boost::dll::fs::path path1(argv[1]); + for (int i = 2; i < argc; ++i) { + boost::dll::fs::path path2(argv[i]); + boost::dll::fs::path res; + for (boost::dll::fs::path::iterator it1 = path1.begin(), it2 = path2.begin(); + it1 != path1.end() && it2 != path2.end() && *it1 == *it2; + ++it1, ++it2) + { + res /= *it1; + } + + path1 = res; + } + + std::string new_argv = path1.string(); + std::cout << "\nPlugins path: " << new_argv << ":\n"; + argv[1] = &new_argv[0]; + /*->*/ + plugins_collector plugins(argv[1]); + + std::cout << "\n\nUnique plugins " << plugins.count() << ":\n"; + plugins.print_plugins(); + // ... +//] + BOOST_ASSERT(plugins.count() >= 3); +} + |