Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Handling pointers when wrapping C++ class with Cython

I'm having trouble when handling pointers with cython. The cython implementation of the class holds a pointer to a C++ instance of class Person. Here's my .pyx file:

person.pyx

cdef class PyPerson:
    cdef Person *pointer

    def __cinit__(self):
        self.pointer=new Person()

    def set_parent(self, PyPerson father):
        cdef Person new_father=*(father.pointer)
        self.c_person.setParent(new_father)        

The C++ method setParent takes a Person object as an argument. Since the attribute pointer of the PyPerson class is a pointer to a Person object, I thought that I could get the object at the adress pointed by *pointer with the syntax *(PyPersonObject.pointer). However when I try to compile it I get the following error

 def set_parent(self, PyPerson father):
    cdef Person new_father=*(father.pointer)
                             ^
------------------------------------------------------------

person.pyx:51:30: Cannot assign type 'Person *' to 'Person'

Does someone knows how can I get to the object at the adress of the pointer? When I do the same in a C++ program I get no error. Here's the implementation of the C++ class in case you want to see it :

person.cpp

Person::Person():parent(NULL){
}

Person::setParent(Person &p){
     parent=&p;
}

NOTE: I can't solve it by holding a Person instance (cdef Peron not_pointer) for other reasons involving the complete class.

like image 357
bengo Avatar asked Mar 02 '17 11:03

bengo


2 Answers

I should have read the entire cython docs on using C++ with Cython. For those who don't know, the dereference operator* can't be used in Cython. Instead you need to import dereference from the cython.operator module. When you want to access the object at the pointed address, you should write dereference(pointer).

In concrete, the answer to my problem is to write cdef Person new_father=dereference(father.c_person).

like image 192
bengo Avatar answered Oct 14 '22 23:10

bengo


One another solution to this might be to index into the pointer at location 0 to dereference a pointer in Cython. For example, suppose we have a golden_ratio C double and a p_double C pointer:

cdef double golden_ratio
cdef double *p_double

We can assign golden_ratio’s address to p_double using the address-of operator, &:

p_double = &golden_ratio

We can now assign to golden_ratio through p_double using our indexing-at-zero-to-dereference syntax:

p_double[0] = 1.618
print(golden_ratio)
# => 1.618
like image 44
Abdul Rehman Avatar answered Oct 15 '22 00:10

Abdul Rehman