[C++-sig] [Boost.Python] Extracting indirect base.
Sebastian Redl
sebastian.redl at getdesigned.at
Fri Jun 9 14:27:20 CEST 2006
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
More information about the Cplusplus-sig
mailing list