cython - callback函數調用

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
>>>

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章