Boost logo

Boost Users :

From: Sebastian Redl (sebastian.redl_at_[hidden])
Date: 2006-06-10 10:07:53


(No luck on C++-sig - is that list even active? There's absolutely no
traffic, not one mail in two days. Anyway, trying again here.)

Hi,

I've got a hand-wrapped plugin interface hierarchy for my program
allowing implementing plugins in Python. This looks approximately like this:

class Plugin
{
public:
  virtual void init() = 0;
  virtual PluginCategory getCategory() = 0; // Subtype of the plugin
  // ...
};

class InputPlugin : public Plugin
{
public:
  virtual void loadData(const string &resource, DataBag &target) = 0;
};

class OutputPlugin : public Plugin
{
public:
  virtual void saveData(const string &resource, const DataBag &source) = 0;
};

These are the plugin interfaces. PluginCategory is an enum identifying
the concrete subtype of the plugin, i.e. either Input or Output.

I've got them wrapped like this:

class PluginWrap : public Plugin, public boost::python::wrapper<Plugin>
{
  virtual void init() { this->get_override("init")(); }
  // ...
};

class InputPlugin : public InputPlugin, public
boost::python::wrapper<InputPlugin>
{
  virtual void loadData(...) { ... }
};

// ...

BOOST_PYTHON_MODULE(myprogram)
{
  class_<PluginWrap, boost::noncopyable>("Plugin")
    .def("init", pure_virtual(&Plugin::init))
    .def( ... )
    ;

  class_<InputPluginWrap, bases<PluginWrap>,
boost::noncopyable>("InputPlugin")
    .def("loadData", ...)
    ;

  // ...
}

A plugin file looks like this:

from myprogram import *

class SomePlugin(InputPlugin):
  def init(self):
    // ...

  // ...

plugins = [SomePlugin()]

I then attempt to load these modules like this:

PythonLoader::load(const path &file)
{
  // Parse file and get namespace object for it. Get the "plugins" list
and extract a python::list. Get the length of that list.
  python::list plugs = ...;
  int len = // get length of plugs

  for(int i = 0; i < len; ++i) {
    try {
      py::object plug = plugs[i];
      Plugin *plugin = py::extract<Plugin *>(plug); // <-------------
      plugins.push_back(plugin);
    } catch(py::error_already_set &e) {
      // handle error
    }
  }
}

Finally, my problem: the extract<Plugin*> call fails:
TypeError: No registered converter was able to extract a C++ pointer to
type Plugin from this Python object of type SomePlugin

So here are my questions:
1) Is this expected behaviour? Does my wrapping not register the
appropriate base pointer extractors?
2) How can I manually register appropriate converters?
3) If 2 is not possible, how can I work around the problem?

Thanks in advance
Sebastian Redl


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net