[C++-sig] How to correctly expose back shared_ptr-ed Python object to C++

Nodir GULYAMOV gelvaos at gmail.com
Fri Aug 7 20:54:46 CEST 2009


Hello All,
I am trying to implement plug-ins system using BOOST Python but a little
stuck. I've read documentation a couple of times and have feeling that
missed something pretty simple.
Below simplified version what I am trying to do:

// abstract Base interface class
class IBasePlugins
{
public:
    virtual ~IBasePlugins() {};
    virtual bool canHandle(int type) = 0;
    virtual void handle() = 0;
};

//some C++ internal plugin (no need to expose to python)
class IntrPlugin : public IBasePlugins
{
public:
    IntrPlugin() : handle_type(1) {}
    bool canHandle(int type) {
         return type == handle_type;
    }
    void handle() { 
         std::cout << "handle() from internal plugin" << std::endl; 
    }
private:
    int handle_type;
};


// class to manage plug-ins

typedef boost::shared_ptr<IPlugins> PluginsPtrType;
typedef vector<PluginsPtrType> VPluginsType;

class PluginsMgr
{
public:
    static void register(PluginsPtrType plugin) {
        vplugins.puch_back(plugin);
    }
    static void run(int type) {
       VPluginsType::iterator it;
       for(it = vplugins.begin(); it != vplugins.end(); it++)
           if( (*it)->canHandle(type) ) (*it)->handle();
    }
private:
   VPluginsType vplugins;
};

// export to python
struct IBasePluginsWrap : public IBasePlugins {
        IBasePluginsWrap(PyObject* self_): self(self_) {}
        bool canHandle(int type) {
            return call_method< bool >(self, "canHandle", type);
        }
        void handle() {
            call_method< void >(self, "handle");
        }

        PyObject* self;
};

BOOST_PYTHON_MODULE(pyPlugins)
{
    class_< IBasePlugins, IBasePluginsWrap, boost::noncopyable >("IBasePlugins")
        .def("canHandle", pure_virtual(&IBasePlugins::canHandle))
        .def("handle", pure_virtual(&IBasePlugins::handle))
        ;

    class_< PluginsMgr >("PluginsMgr")
        .def("registerPlugin", &PlgMgr::registerPlugin)
        .staticmethod("registerPlugin")
        .def("run", &PlgMgr::run)
        .staticmethod("run")
        ;

    register_ptr_to_python<PluginsPtrType>();
}


Then I am using it from python as follows:

from pyPlugins import *

class PyTestPlugin(IBasePlugins):
      def __init__(self):
          self.handle_type = 2
      def canHandle(self, type):
          return type == handle_type
      def handle(self):
          print "handle() from python plugin"


pm = PluginsMgr()
testplg = PyTestPlugin()
pm.registerPlugin(testplg)

And have error that C++ signature mismatch.

Thank you in advance. I will really appreciate any help.

Kind regards,
Nodir


More information about the Cplusplus-sig mailing list