问题
I'm trying to use a C library which uses a callback function (callback_function) to provide a pointer to a struct I'd like to wrap (glp_tree).
What is the correct way to initialize an instance with a pointer not created in __cinit__
? I can't find an example of this pattern in the cython documentation.
I have some working code (see below), which casts the pointer to an integer and back, but I'm not sure this is good practice / sane.
cdef extern from "stdint.h":
ctypedef unsigned long long uint64_t
cdef extern from "glpk.h":
ctypedef struct glp_tree:
pass
cdef void callback_func(glp_tree* tree, void *info):
treeobj = Tree(<uint64_t>tree) // cast to an integer...
cdef class Tree:
cdef glp_tree* ptr
def __init__(self, uint64_t ptr):
self.ptr = <glp_tree*>ptr // ... and back to a pointer
Passing the glp_tree object directly seems to work (although it's not what I want to do), but trying to pass the pointer results in a compiler error:
Cannot convert 'glp_tree *' to Python object
回答1:
Instead of using __init__
/__cinit__
(which always expects Python objects as arguments), you can use a custom @staticmethod cdef
to create instances:
cdef class Tree:
cdef glp_tree* ptr
def __init__(self, *args):
raise TypeError('Cannot create instance from Python')
@staticmethod
cdef Tree create(glp_tree* ptr):
obj = <Tree>Tree.__new__(Tree) # create instance without calling __init__
obj.ptr = ptr
return obj
回答2:
Casting a pointer to an integer is an option, but then the correct type to use is uintptr_t
, not uint64_t
(it's self-documenting and always has the right width for the platform).
The problem is that constructing a Tree
is a Python operation, as you can clearly see in the cython -a
output. The input to the constructor has to be converted to Python data structures, and pointers have no obvious conversion.
回答3:
This will work
cdef class Tree:
cdef glp_tree* ptr
def __init__(self, long ptr):
self.ptr = <glp_tree*>PyLong_AsVoidPtr(ptr)
来源:https://stackoverflow.com/questions/18695402/wrapping-a-pre-initialized-pointer-in-a-cython-class