15.10 用Cython包装C代码

问题

You want to use Cython to make a Python extension module that wraps around anexisting C library.

解决方案

Making an extension module with Cython looks somewhat similar to writing a hand‐written extension, in that you will be creating a collection of wrapper functions. How‐ever, unlike previous recipes, you won’t be doing this in C—the code will look a lot morelike Python.As preliminaries, assume that the sample code shown in the introduction to this chapterhas been compiled into a C library called libsample. Start by creating a file namedcsample.pxd that looks like this:

cimport csamplefrom libc.stdlib cimport malloc, free...

cdef class Point:
cdef csample.Point *_c_pointdef cinit(self, double x, double y):

self._c_point = <csample.Point *> malloc(sizeof(csample.Point))self._c_point.x = xself._c_point.y = y

def dealloc(self):free(self._c_point)property x:def get(self):return self._c_point.xdef set(self, value):self._c_point.x = valueproperty y:def get(self):return self._c_point.ydef set(self, value):self._c_point.y = valuedef distance(Point p1, Point p2):return csample.distance(p1._c_point, p2._c_point)
Here, the cdef class Point is declaring Point as an extension type. The class variablecdef csample.Point *_c_point is declaring an instance variable that holds a pointerto an underlying Point structure in C. The cinit() and dealloc() methodscreate and destroy the underlying C structure using malloc() and free() calls. Theproperty x and property y declarations give code that gets and sets the underlyingstructure attributes. The wrapper for distance() has also been suitably modified toaccept instances of the Point extension type as arguments, but pass the underlyingpointer to the C function.Making this change, you will find that the code for manipulating Point objects is morenatural:

>>> import sample
>>> p1 = sample.Point(2,3)
>>> p2 = sample.Point(4,5)
>>> p1
<sample.Point object at 0x100447288>
>>> p2
<sample.Point object at 0x1004472a0>
>>> p1.x
2.0
>>> p1.y
3.0
>>> sample.distance(p1,p2)
2.8284271247461903
>>>

This recipe has illustrated many of Cython’s core features that you might be able toextrapolate to more complicated kinds of wrapping. However, you will definitely wantto read more of the official documentation to do more.The next few recipes also illustrate a few additional Cython features.

文章导航