in fact, I found a much better solution, much more element by using the
wrapper<T> class and having the boost::python::object instanciated in C++
rather than in the interpreter (if my interpretation of the interpreted is
correctly interpreted in this context).
So each plugin is a python object and thanks to wrapper<>, the Python user
can now derive from a base Plugin class and implement whatever callbacks
they need, instead of doing the strange file gibberish I did before.
For those wondering how it works:
1- Make a Base class with pure virtual methods that you want the python
user to implement
class Plugin
{
public:
Plugin(Server&); // Server is whatever C++ code control the plugin in
fact
virtual ~Plugin() = default;
// evaluates the plugin
virtual bool eval(int x) = 0;
// use some Server function
void a_function(const std::string& val);
private:
Server& server;
};
2- Make an intermediate class which inherits from Base and
boost::python::wrapper<Base> in which the user's function are implemented
like in the following example:
class PluginWrapper final : public Plugin, public wrapper<Plugin>
{
using Plugin::Plugin;
void eval(int x) override
{
return get_override("eval")(x); // This will call the user's Python
code
}
};
3- Expose your API in Python as usual:
BOOST_PYTHON_MODULE(Foobar)
{
class_<Server>("Server");
class_
On 13.01.2017 12:46, David Bellot wrote:
- or encapsulate each plugin in an independent "environment" ? Hard to tell without knowing these plugins. Right now it sounds like that's a question only you can answer. :-)
The plugins are quite simple in fact:
The Python code define a few functions like
def on_value_update(x): blah blah blah return foobar
and they can have global variables (if it's a problem I can forbid user's to use those global variables in their plugins).
For avoidance of doubt: "global variables" aren't variables in module-scope (they are still "local" to the module, and don't cause any problem.)
Each plugin is defined in a .py file and at runtime I load all those files, one after each other.
That sounds all good. Each plugin corresponds to a Python module (which is an object), and you can call module-level functions (such as 'on_value_update') on that object as if it was a method. So if you keep a list of module objects in your C++ runtime, you can access their methods without any global functions colliding. (See http://boostorg.github.io/python/doc/html/tutorial/tutorial/ embedding.html#tutorial.embedding.using_the_interpreter for how to embed Python code into your C++ app.)
In case that doesn't help, can you explain where in your current setup the plugin methods overwrite each other as they are loaded ?
Stefan
--
...ich hab' noch einen Koffer in Berlin...
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman /listinfo.cgi/boost