Boost Python - 未绑定的方法调用

时间:2017-08-21 22:48:01

标签: c++ python-2.7 boost-python

我正在尝试使用嵌入在C ++中的Python和Boost :: python。

我的嵌入式脚本应该使用装饰器来注册他们的方法如下:

class Test:

    def __init__(self, object_id):
        self.object_id = object_id


    @decorator('my_id_1')
    def func1(self):    
        print("{}.func1".format(self.object_id)) 
在C ++端声明了

decorator,定义了__init____call__的方法。一切正常,直到调用方法,导致SIGSEGV或SIGARBT。

以下是我想用Python做的一个例子:

#CPP side
item = {}

class decorator:
    def __init__(self, _id):
        self._id = _id

    def __call__(self, func):
        item[self._id] = func #saved as PyObject* in CPP
        print func
        return func

#Script side            
class Test(CppBase):

    def __init__(self, object_id):
        CppBase.__init__(self)
        self.object_id = object_id


    @decorator('my_id_1')
    def func1(self):    
        print("{}.func1".format(self.object_id)) 


    @decorator('my_id_2')
    def func2(self):    
        print("{}.func2".format(self.object_id)) 

#CPP side
obj1 = Test("obj1")

item['my_id_1'](obj1) #The crash append here

要进行通话,我使用以下功能:boost::python::call<void>(my_PyObject_func, boost::ref(my_obj_instance))

我不会把我所有的C ++代码都放在一起,因为我实际上正在更新一个由旧的Python C API构建的工作项目,整个API非常庞大。但是,如果您认为我忘了它的一些重要部分,请告诉我,我会发布这些部分。此外,我删除了很多简单的检查,例如确保全局Python var包含我的对象,没有发生python错误或者哈希包含请求的id,以使代码更轻。

这是我的C ++对象定义

class CppBase: public boost::python::object {
    public:
        CppBase();

        void open(std::string, boost::python::tuple arg);

        void setRoutes(const std::hash<std::string, const Route*>&);

        inline std::hash<std::string, const Route*>*const routes() const { return route; }

    private:
      std::string name;
      QHash<std::string, const Decorator*> *route;
};

class Decorator {
    public:
        Decorator(std::string identifier);

        PyObject* call(PyObject* func);

        void invoke(boost::python::object&, boost::python::tuple) const;

        static void commit(CppBase&);
    private:
        PyObject* method;

        std::string identifier;

        static std::hash<std::string, const Decorator*> routes;
};

以下是我注册Python模块的方法

BOOST_PYTHON_MODULE(app)
{
    boost::python::class_<CppBase, boost::noncopyable>("CppApp") //I tried to remove 'noncopyable', nothing change
    ;

    boost::python::class_<Decorator, boost::noncopyable>("decorator", boost::python::init<std::string>())
        .def("__repr__", &Decorator::repr)
        .def("__call__", &Decorator::call)
    ;
}

以下是CppBase::open的实现,我认为这是我班级定义中唯一重要的实现。

...
void CppBase::open(std::string id, boost::python::tuple arg /* unused so far */){
    boost::python::call<void>(route->value(id), boost::ref(*this))
}
...

以下是使用此示例运行的Python脚本示例:

class MyScriptSubClass(CppApp):

    def __init__(self, object_id):
        CppBase.__init__(self)
        self.object_id = object_id


    @decorator('my_id_1')
    def func1(self):    
        print("{}.func1".format(self.object_id)) 

以下是我尝试使一切正常的方法

//... Creating Python context, Executing the Script file...

boost::python::object cls(main_module.attr("MyScriptSubClass")); //Getting the classDefinition

CppBase core = boost::python::extract<CppBase>(cls()); //Instanciating the object with the previous catched definition

Decorator::commit(core); //Save all the decorator intercepted until now into the object

core.open('my_id_1'); //Calling the function matching with this id

我希望我把事情弄清楚。

事先,谢谢。

0 个答案:

没有答案