我研究了一下,贴下代码吧。
```
root@arch area: # 首先是 area.h 和 area.c
root@arch area: cat area.h
#ifndef _AREA_H
#define _AREA_H
struct Square {
float length;
float width;
};
typedef struct Square *pSquare;
float calc_area(pSquare);
#endif /* area.h */
root@arch area: cat area.c
#include <stdio.h>
#include <stdlib.h>
#include "area.h"
float calc_area(pSquare s) {
return s->length * s->width;
}
int main(void) {
pSquare s = (pSquare)malloc(sizeof(struct Square));
if (s == NULL) {
printf("memory not enough");
exit(1);
}
s->length = 10.0;
s->width = 3.0;
printf("area of the square: %f\n", calc_area(s));
free(s);
}
root@arch area: # 运行一下
root@arch area: cc area.c && ./a.out && rm a.out
area of the square: 30.000000
root@arch area: # 为 area.c 定义包裹的 Cython 头文件
root@arch area: cat carea.pxd
cdef extern from "area.h":
cdef struct Square:
float length
float width
ctypedef Square *pSquare;
cdef float calc_area(pSquare);
root@arch area: # 为 python 版本 Square 定义 Cython 头文件
root@arch area: cat py_area.pxd
cimport carea
cdef class Square:
cdef carea.pSquare _square
cpdef float calc_area(Square)
root@arch area: # 为 python 版本 Square 包裹一下
root@arch area: cat py_area.pyx
from cpython.mem cimport PyMem_Malloc, PyMem_Free
cimport carea
cdef class Square:
def __cinit__(self, length, width):
self._square = <carea.pSquare>PyMem_Malloc(sizeof(carea.Square))
if not self._square:
raise MemoryError("Memory not enough")
self._square.length = length
self._square.width = width
def __dealloc__(self):
PyMem_Free(self._square)
cpdef float calc_area(self):
return carea.calc_area(self._square)
root@arch area: # 调用一下
root@arch area: # 哦不,先写好
setup.py ,然后编译
root@arch area: cat
setup.py from distutils.core import setup
from distutils.extension import Extension
from
Cython.Build import cythonize
ext_modules = cythonize([
Extension("py_area", ["py_area.pyx", "area.c"])
])
setup(ext_modules=ext_modules)
root@arch area: python3
setup.py build_ext --inplace
running build_ext
building 'py_area' extension
gcc -pthread -Wno-unused-result -Wsign-compare -DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes -march=x86-64 -mtune=generic -O2 -pipe -fstack-protector-strong -march=x86-64 -mtune=generic -O2 -pipe -fstack-protector-strong -march=x86-64 -mtune=generic -O2 -pipe -fstack-protector-strong -fPIC -I/usr/include/python3.6m -c py_area.c -o build/temp.linux-x86_64-3.6/py_area.o
gcc -pthread -Wno-unused-result -Wsign-compare -DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes -march=x86-64 -mtune=generic -O2 -pipe -fstack-protector-strong -march=x86-64 -mtune=generic -O2 -pipe -fstack-protector-strong -march=x86-64 -mtune=generic -O2 -pipe -fstack-protector-strong -fPIC -I/usr/include/python3.6m -c area.c -o build/temp.linux-x86_64-3.6/area.o
gcc -pthread -shared -Wl,-O1,--sort-common,--as-needed,-z,relro -Wl,-O1,--sort-common,--as-needed,-z,relro build/temp.linux-x86_64-3.6/py_area.o build/temp.linux-x86_64-3.6/area.o -L/usr/lib -lpython3.6m -o /root/tests/area/
py_area.cpython-36m-x86_64-linux-gnu.soroot@arch area: # 调用
root@arch area: ipython
Python 3.6.0 (default, Dec 24 2016, 08:03:08)
Type "copyright", "credits" or "license" for more information.
IPython 5.1.0 -- An enhanced Interactive Python.
? -> Introduction and overview of IPython's features.
%quickref -> Quick reference.
help -> Python's own help system.
object? -> Details about 'object', use 'object??' for extra details.
In [1]: import py_area
In [2]: a = py_area.Square(10, 20)
In [3]: a.calc_area()
Out[3]: 200.0
In [4]:
Do you really want to exit ([y]/n)?
root@arch area:
```