BoostDLL : Multiple plugins in a single *.so/*.dll file
Hi, I am currently able to load each plugin in a given shared library. i.e. one plugin for each corresponding *.so/*.dll file However, as the number of plugins increases, I am wondering if there is a way to structure my plugins so that it all resides in a single *.so/*.dll file Additionally, how should one create the individual plugins in a single *.so/*.dll to be able to call their static method ? I have not found such examples so I am not sure if I am using the wrong search terms or it is currently not supported by design in BoostDLL. Cheers -- Nicholas Yue Graphics - Arnold, Alembic, RenderMan, OpenGL, HDF5 Custom Dev - C++ porting, OSX, Linux, Windows http://au.linkedin.com/in/nicholasyue https://vimeo.com/channels/naiadtools
On Sun, May 17, 2020 at 01:10:39PM -0700, Nicholas Yue via Boost-users wrote:
Hi,
I am currently able to load each plugin in a given shared library. i.e. one plugin for each corresponding *.so/*.dll file
However, as the number of plugins increases, I am wondering if there is a way to structure my plugins so that it all resides in a single *.so/*.dll file
Additionally, how should one create the individual plugins in a single *.so/ *.dll to be able to call their static method ?
I have not found such examples so I am not sure if I am using the wrong search terms or it is currently not supported by design in BoostDLL.
Create a class for each plugin and a factory function for each of the plugin classes. I've done that and it works like a charm. HTH Stefan
Hi Stefan, I did try with the factory approach but I was only able to gain access to one of the plugin. I have build a single shared library called MultiplePlugins that contains two plugins SourcePlugin and SinkPlugin but I have not found a way to iterate the individual factory method 8<------8<------8<------8<------8<------8<------8<------8<------ ================ AbstractPlugin.h ================ #pragma once #include <boost/format.hpp> #include <boost/shared_ptr.hpp> #include <iostream> class AbstractPlugin { public: AbstractPlugin() {}; virtual ~AbstractPlugin() {}; virtual void compute() = 0; protected: std::string _name; }; typedef boost::shared_ptr<AbstractPlugin> PluginSharedPtr; ============ SinkPlugin.h ============ #include "AbstractPlugin.h" class SinkPlugin : public AbstractPlugin { public: SinkPlugin(); virtual ~SinkPlugin(); virtual void compute(); // Factory method static PluginSharedPtr create(); }; ============== SourcePlugin.h ============== #include "AbstractPlugin.h" class SourcePlugin : public AbstractPlugin { public: SourcePlugin(); virtual ~SourcePlugin(); virtual void compute(); // Factory method static PluginSharedPtr create(); }; ============== SinkPlugin.cpp ============== #include "SinkPlugin.h" #include "boost/dll/alias.hpp" SinkPlugin::SinkPlugin() { _name = "SinkPlugin"; } SinkPlugin::~SinkPlugin() { } void SinkPlugin::compute() { std::cout << boost::format("Plugin name is '%1%'") % _name << std::endl; } PluginSharedPtr SinkPlugin::create() { return boost::shared_ptr<SinkPlugin>(new SinkPlugin()); } BOOST_DLL_ALIAS(SinkPlugin::create, create_plugin) ================ SourcePlugin.cpp ================ #include "SourcePlugin.h" #include "boost/dll/alias.hpp" SourcePlugin::SourcePlugin() { _name = "SourcePlugin"; } SourcePlugin::~SourcePlugin() { } void SourcePlugin::compute() { std::cout << boost::format("Plugin name is '%1%'") % _name << std::endl; } // Factory method PluginSharedPtr SourcePlugin::create() { return boost::shared_ptr<SourcePlugin>(new SourcePlugin()); } BOOST_DLL_ALIAS(SourcePlugin::create, create_plugin) ======== main.cpp ======== #include "SinkPlugin.h" #include "SourcePlugin.h" #include <boost/filesystem.hpp> #include <boost/function.hpp> #include <boost/dll/import.hpp> int main() { std::cout << "Boost DLL testing ..." << std::endl; /* Load the plugin from current working path */ boost::filesystem::path pluginPath = boost::filesystem::current_path() / boost::filesystem::path("MultiplePlugins"); std::cout << "Load Plugin from " << pluginPath << std::endl; typedef PluginSharedPtr(PluginCreate)(); boost::function <PluginCreate> pluginCreator; try { pluginCreator = boost::dll::import_alias<PluginCreate>(pluginPath, "create_plugin", boost::dll::load_mode::append_decorations); } catch (const boost::system::system_error &err) { std::cerr << "Cannot load Plugin from " << pluginPath << std::endl; std::cerr << err.what() << std::endl; return -1; } /* create the plugin */ auto plugin = pluginCreator(); plugin->compute(); return 0; } ============== CMakeLists.txt ============== add_library ( MultiplePlugins SHARED SinkPlugin.cpp SourcePlugin.cpp ) add_executable ( load_plugins main.cpp ) target_link_libraries ( load_plugins ${Boost_LIBRARIES} ${CMAKE_DL_LIBS} ) On Sun, 17 May 2020 at 23:46, Stefan Naewe via Boost-users < boost-users@lists.boost.org> wrote:
On Sun, May 17, 2020 at 01:10:39PM -0700, Nicholas Yue via Boost-users wrote:
Hi,
I am currently able to load each plugin in a given shared library. i.e. one plugin for each corresponding *.so/*.dll file
However, as the number of plugins increases, I am wondering if there is a way to structure my plugins so that it all resides in a single *.so/*.dll file
Additionally, how should one create the individual plugins in a single *.so/ *.dll to be able to call their static method ?
I have not found such examples so I am not sure if I am using the wrong search terms or it is currently not supported by design in BoostDLL.
Create a class for each plugin and a factory function for each of the plugin classes. I've done that and it works like a charm.
HTH Stefan _______________________________________________ Boost-users mailing list Boost-users@lists.boost.org https://lists.boost.org/mailman/listinfo.cgi/boost-users
-- Nicholas Yue Graphics - Arnold, Alembic, RenderMan, OpenGL, HDF5 Custom Dev - C++ porting, OSX, Linux, Windows http://au.linkedin.com/in/nicholasyue https://vimeo.com/channels/naiadtools
On 19/05/2020 07:26, Nicholas Yue wrote:
I did try with the factory approach but I was only able to gain access to one of the plugin.
I have build a single shared library called MultiplePlugins that contains two plugins SourcePlugin and SinkPlugin but I have not found a way to iterate the individual factory method [...] BOOST_DLL_ALIAS(SinkPlugin::create, create_plugin) [...] BOOST_DLL_ALIAS(SourcePlugin::create, create_plugin)
You can't have two symbols in the same library with the same name/alias; that's either a linker error or one will shadow the other. You'll have to use one of the other techniques to find symbols to load, such as using a named section instead of a named alias.
participants (3)
-
Gavin Lambert
-
Nicholas Yue
-
Stefan Naewe