This is an archival dump of old wiki content --- see scipy.org for current material.
Please see http://scipy-cookbook.readthedocs.org/

Overview

Pyrex is a language for writing C extensions to Python. Its syntax is very similar to writing Python. A .pyx file is compiled to a .c file, which is then compiled like a standard C extension module for Python. Many people find writing extension modules with Pyrex preferable to writing them in C or using other tools, such as SWIG.

See http://numeric.scipy.org/ for an explanation of the __array_struct__ interface. The following packages support the interface:

  • NumPy (all versions)

  • Numeric (>=24.2)

  • numarray (>=1.5.0)

Sharing data malloced by a Pyrex-based extension

Here is a Pyrex file which shows how to export its data using the __array_struct__ array interface. This allows various Python types to have a view of the data without actually copying the data itself.

cdef extern from "Python.h":
 ctypedef int Py_intptr_t
 void Py_INCREF(object)
 void Py_DECREF(object)
 object PyCObject_FromVoidPtrAndDesc( void* cobj, void* desc, void (*destr)(void *, void *))
 
cdef extern from "stdlib.h":
 ctypedef int size_t
 ctypedef long intptr_t
 void *malloc(size_t size)
 void free(void* ptr)

# for PyArrayInterface:
CONTIGUOUS=0x01
FORTRAN=0x02
ALIGNED=0x100
NOTSWAPPED=0x200
WRITEABLE=0x400

ctypedef struct PyArrayInterface:
 int version # contains the integer 2 as a sanity check
 int nd # number of dimensions
 char typekind # kind in array --- character code of typestr
 int itemsize # size of each element
 int flags # flags indicating how the data should be interpreted
 Py_intptr_t *shape # A length-nd array of shape information
 Py_intptr_t *strides # A length-nd array of stride information
 void *data # A pointer to the first element of the array

cdef void free_array_interface( void* ptr, void *arr ):
 cdef PyArrayInterface* inter

 inter = <PyArrayInterface*>ptr
 arrpy = <object>arr
 Py_DECREF( arrpy )
 free(inter)

ctypedef unsigned char fi
ctypedef fi* fiptr
cdef class Unsigned8Buf:
 cdef fiptr data
 cdef Py_intptr_t shape[2]
 cdef Py_intptr_t strides[2]
 
 def __init__(self, int width, int height):
 cdef int bufsize
 bufsize = width*height*sizeof(fi)
 self.data=<fiptr>malloc( bufsize )
 if self.data==NULL: raise MemoryError("Error allocating memory")
 self.strides[0]=width
 self.strides[1]=1 # 1 byte per element
 
 self.shape[0]=height
 self.shape[1]=width
 
 def __dealloc__(self):
 free(self.data)
 
 property __array_struct__:
 def __get__(self):
 cdef PyArrayInterface* inter

 cdef Py_intptr_t *newshape # A length-nd array of shape information
 cdef Py_intptr_t *newstrides # A length-nd array of stride information
 cdef int nd

 nd = 2

 inter = <PyArrayInterface*>malloc( sizeof( PyArrayInterface ) )
 if inter is NULL:
 raise MemoryError()

 inter.version = 2
 inter.nd = nd
 inter.typekind = 'u'[0] # unsigned int
 inter.itemsize = 1
 inter.flags = NOTSWAPPED | ALIGNED | WRITEABLE
 inter.strides = self.strides
 inter.shape = self.shape
 inter.data = self.data
 Py_INCREF(self)
 obj = PyCObject_FromVoidPtrAndDesc( <void*>inter, <void*>self, free_array_interface)
 return obj

Using data malloced elsewhere with a Pyrex-based extension

One example is the get_data_copy() function of _cam_iface_shm.pyx in the motmot camera utilities software. In this use example, an image is copied from shared memory into an externally malloced buffer supporting the __array_struct__ interface. (The shared memory stuff has only been tested on linux, but the rest should work anywhere.)

See also


CategoryCookbook

SciPy: Cookbook/ArrayStruct_and_Pyrex (last edited 2015年10月24日 17:48:23 by anonymous)

AltStyle によって変換されたページ (->オリジナル) /