find_cheeses.h 與 find_cheeses.c都是標準的c接口;
1. find_cheeses.h文件
// find_cheeses.h 文件
typedef void (*cheesefunc)(char *name, void *user_data);
void find_cheeses(cheesefunc user_func, void *user_data);
*.h上的函數,需在pyx中重新cython化;
2. find_cheeses.c文件
/*
* An example of a C API that provides a callback mechanism.
*/
#include "cheesefinder.h"
static char *cheeses[] = {
"cheddar",
"camembert",
"that runny one",
0
};
void find_cheeses(cheesefunc user_func, void *user_data) {
char **p = cheeses;
while (*p) {
user_func(*p, user_data);
++p;
}
}
3. cheese.pyx文件
#
# Cython wrapper for the cheesefinder API
#
cdef extern from "cheesefinder.h":
ctypedef void (*cheesefunc)(char *name, void *user_data)
void find_cheeses(cheesefunc user_func, void *user_data)
def find(f):
find_cheeses(callback, <void*>f)
cdef void callback(char *name, void *f):
(<object>f)(name.decode('utf-8'))
4. setup.py
from distutils.core import setup
from distutils.extension import Extension
from Cython.Build import cythonize
setup(
name = 'callback',
ext_modules=cythonize([
Extension("cheese", ["cheese.pyx", "cheesefinder.c"]),
]),
)
5. 測試code
import cheese
def report_cheese(name):
print("Found cheese: " + name)
cheese.find(report_cheese)
6. 測試結果
J:\mySVN\cython\Demos\callback>python
Python 3.7.0 (v3.7.0:1bf9cc5093, Jun 27 2018, 04:06:47) [MSC v.1914 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import cheese
>>> import run_cheese
Found cheese: cheddar
Found cheese: camembert
Found cheese: that runny one
>>>