Wrapping a pre-initialized pointer in a cython class

I am trying to use a C library that uses a callback function (callback_function) to provide a pointer to the structure I would like to wrap (glp_tree).

What is the correct way to initialize an instance with a pointer not created in __cinit__ ? I can not find an example of this template in the cython documentation.

I have a working code (see below) in which a pointer to the integer and vice versa, but I'm not sure if this is good practice / normal work.

 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 works (although this is not what I want to do), but trying to pass a pointer results in a compiler error:

 Cannot convert 'glp_tree *' to Python object 
+4
source share
3 answers

Instead of using __init__ / __cinit__ (which always expects Python objects as arguments), you can use the custom @staticmethod cdef to instantiate:

 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 
+4
source

Casting a pointer to an integer is an option, but then the correct type to use is uintptr_t , not uint64_t (it is self-documenting and always has the correct width for the platform).

The problem is that building the Tree is a Python operation, as you can clearly see in the output of cython -a . The constructor entry must be converted to Python data structures, and pointers do not have an obvious conversion.

+2
source

It will work

 cdef class Tree: cdef glp_tree* ptr def __init__(self, long ptr): self.ptr = <glp_tree*>PyLong_AsVoidPtr(ptr) 
-one
source

Source: https://habr.com/ru/post/1501267/


All Articles