How to pass Python instance to C++ via Python/C API -


i'm extending library python (2.7) wrapping interfaces swig 2.0, , have graph object in want create visitor. in c++, interface looks this:

    struct visitor     {         virtual void onstatebegin() = 0;         virtual void onnode(node* n) = 0;         virtual void onstateend() = 0;     }; 

i define class in python equivalent, defined in python, allow definition of visitor:

class graphvisitor:     def __init__(self, label):         self._label = label         print("__init__(self,{0})".format(self._label))     def onstatebegin(self):         print("onstatebegin()" + self._label)     def onnode(self, i_node):         print("onnode()" + self._label)     def onstateend(self):         print("onstateend()" + self._label) 

and i'm trying create instance of graphvisitor in python script, , call methods onstatebegin(), onnode(), , onstateend() given instance c++. here's i'd in python:

#model swig wrapped class mvis = graphvisitor("this test") model.visit("mvis") # i'm not sure how pass instance 'mvis' c++? 

and in c++ wrapped swig, i'm not sure how @ instance 'mvis'? can call functions defined in python no problem, instances has me stumped!

in order solve problem, retrieved class module given it's module name , class name (the code below assumes module hasn't been loaded):

void model::visit(const char* mod_name, const char* class_name) {     pyerr_clear();     pyobject* mod_name_obj = pystring_fromstring(mod_name);     pyobject* class_name_obj = pystring_fromstring(class_name);      pyobject* py_module = pyimport_import(mod_name_obj);     pyobject* err_1 = pyerr_occurred();     if(err_1)         pyerr_print(); 

once had module, looked class it's dictionary:

    if(py_module)     {         pyobject* py_module_dict = pymodule_getdict(py_module);         pyobject* py_class = pydict_getitem(py_module_dict, class_name_obj); 

i simplified problem bit instantiating python class in c++, created visitor, , visited it:

        if(py_class && pyclass_check(py_class) && pycallable_check(py_class))         {             pyobject* inst = pyinstance_new(py_class, 0, 0);              if(inst && pyinstance_check(inst))             {                 imodel::ivisitorptr py_visitor = new pymodelvisitor(inst);                  _model->visit(py_visitor);             }         }     } } 

the visitor had 3 functions onstatebegin(), onnode(), , onstateend(). added swig python binding generator option generate header file external access swig runtime -external-runtime option, create class in c++ (inode* below) , pass python argument python onnode() member function follows (error checking removed brevity):

visitorctrl onnode(inode* node) {     node* node_impl = new nodeimpl(node);     pyobject* pynode = swig_newpointerobj(node_impl, swig_typequery("node *"), 0);     pyobject* result = pyobject_callmethodobjargs(_inst, pystring_fromstring("onnode"), pynode, 0);      long rivis = pyint_aslong(result);      return(static_cast<visitorctrl>(rivis)); } 

Comments

Popular posts from this blog

java - Spring Data JPA: Why findOne(id) executing delete query internally? -

python - Mongodb How to add addtional information when aggregating? -

java - Incorrect order of records in M-M relationship in hibernate -