Ayaz Salikhov Ayaz Salikhov - 3 months ago 12
Python Question

A way to pass c++ object to another object's method in cython

I have two classes (let's assume the most simple ones, implementation is not important). My

defs.pxd
file (with cython defs) looks like this:

cdef extern from "A.hpp":
cdef cppclass A:
A() except +

cdef extern from "B.hpp":
cdef cppclass B:
B() except +
int func (A)


My
pyx
file (with python defs) looks like this:

from cython.operator cimport dereference as deref
from libcpp.memory cimport shared_ptr

cimport defs

cdef class A:
cdef shared_ptr[cquacker_defs.A] _this

@staticmethod
cdef inline A _from_this(shared_ptr[cquacker_defs.A] _this):
cdef A result = A.__new__(A)
result._this = _this
return result

def __init__(self):
self._this.reset(new cquacker_defs.A())

cdef class B:
cdef shared_ptr[cquacker_defs.B] _this

@staticmethod
cdef inline B _from_this(shared_ptr[cquacker_defs.B] _this):
cdef B result = B.__new__(B)
result._this = _this
return result

def __init__(self):
self._this.reset(new cquacker_defs.B())

def func(self, a):
return deref(self._this).func(deref(a._this))


The thing is that
deref(self._this)
works right, but
deref(a._this)
doesn't with this error:

Invalid operand type for '*' (Python object)


How can I pass one python object's internal c++ object to another one's method in python?

Answer
def func(self, A a):
    return # ... as before

You need to tell Cython that a is of type A (the type is checked when you call it). That way it knows about a._this and doesn't treat it as a Python attribute lookup. You can only access cdefed attributes if Cython knows the type at comple time.

Comments