How can I do this:
cdef class Tree:
cdef object key
cdef Tree left
cdef Tree right
cdef PyObject** find(self, key):
# get the address of self
# return &self
# return &(<PyObject*>self)
&self
fails with Cannot take address of Python variable
.&(<PyObject*>self)
fails with Taking address of non-lvalue
, and I'm not sure that self
is actually a PyObject*
.<void*>self
and <PyObject*>self
works just fine to get a pointer to self.
from ctypes import addressof, c_int
from cpython.ref cimport PyObject
from cython.operator import address
from libc.stdio cimport printf
cdef class A:
cdef object py
cdef int c
def __init__(self, py, c):
self.py = py
self.c = c
cdef void* addrvoid(self):
return <void*>self
cdef PyObject* addr(self):
return <PyObject*>self
cpdef run():
cdef A a
a = A([], 1)
# these are all equivalent
printf('a=%lu\n', <void*>a)
printf('a=%lu\n', <PyObject*>a)
printf('a=%lu\n', a.addrvoid())
printf('a=%lu\n', a.addr())
# type casting doesnt work with the extension's c attributes because it
# will translate to the arrow operator, like: (void *)__pyx_v_a->b)
# printf('%lu\n', <void*>a.c)
# printf('%lu\n', <void*>(a.c))
# printf('%lu\n', <PyObject*>(a.c))
# and address() dont work with python attributes
# printf('a.py=%lu\n', <void*>address(a.py))
# but address works with c attributes
printf('a.c=%lu\n', address(a.c))
# and type casting works with python attributes
printf('a.py=%lu\n', <void*>(a.py))
# it works with ctypes too
i = c_int(1)
print('cint=' + str(id(i)))
printf('cint=%lu\n', <void*>i)
# but it evaluates to the address of the python object
print('cint=' + str(addressof(i)))
Running this code will result in something like:
a=140516369271496
a=140516369271496
a=140516369271496
a=140516369271496
a.c=140516369271528
a.py=140516452410632
cint=140516465032184
cint=140516465032184
cint=140516465032264
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With