Handling pointers when wrapping C++ class with Cython
Asked Answered
P

2

11

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.

P answered 2/3, 2017 at 11:44 Comment(0)
P
14

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).

P answered 3/3, 2017 at 11:33 Comment(1)
tks, the issue troubled me about *thisDaisydaitzman
J
5

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
Jura answered 14/12, 2020 at 8:10 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.