BoostDLL : Multiple plugins in a single *.so/*.dll file

classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

BoostDLL : Multiple plugins in a single *.so/*.dll file

Boost - Users mailing list
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

_______________________________________________
Boost-users mailing list
[hidden email]
https://lists.boost.org/mailman/listinfo.cgi/boost-users
Reply | Threaded
Open this post in threaded view
|

Re: BoostDLL : Multiple plugins in a single *.so/*.dll file

Boost - Users mailing list
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
[hidden email]
https://lists.boost.org/mailman/listinfo.cgi/boost-users
Reply | Threaded
Open this post in threaded view
|

Re: BoostDLL : Multiple plugins in a single *.so/*.dll file

Boost - Users mailing list
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 <[hidden email]> 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
[hidden email]
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

_______________________________________________
Boost-users mailing list
[hidden email]
https://lists.boost.org/mailman/listinfo.cgi/boost-users
Reply | Threaded
Open this post in threaded view
|

Re: BoostDLL : Multiple plugins in a single *.so/*.dll file

Boost - Users mailing list
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.

_______________________________________________
Boost-users mailing list
[hidden email]
https://lists.boost.org/mailman/listinfo.cgi/boost-users