2015-03-01 2 views
4

Как я могу это сделать:Как я могу получить адрес сам?

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 терпит неудачу с Cannot take address of Python variable.
  • &(<PyObject*>self) не работает Taking address of non-lvalue, и я не уверен, что self на самом деле является PyObject*.
+0

когда вы передаете 'self' это уже ссылка. Если вы завершаете класс C++ и хотите удалить экземпляр класса C++ [вы можете следовать распространенной практике, предлагаемой здесь] (http://docs.cython.org/src/userguide/wrapping_CPlusPlus.html#create-cython-wrapper -class) –

+0

Эй, @SaulloCastro, я не обволакиваю какой-либо код, просто используя Cython, я хочу использовать указатель на объект, идея состоит в том, чтобы иметь один уровень косвенности. –

+0

Чтобы добавить некоторый контекст, я реализую Tree in pure cython как упражнение, чтобы изучить язык, и потому что я хочу реализовать другие структуры данных. Я хочу использовать указатели для упрощения кода удаления, особенно для удаления листовых узлов, идея заключается в том, чтобы избежать использования объекта parent, будь то переменная, проходящая вокруг или атрибут Node. –

ответ

1

<void*>self и <PyObject*>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))) 

Выполнение этого кода приведет к чему-то вроде:

а = 140516369271496
а = 140516369271496
а = 140516369271496
а = 140516369271496
ас = 140516369271528
a.py = 140516452410632
cint = 140516465032184
cint = 140516465032184
CInt = 140516465032264

Смежные вопросы