【发布时间】:2015-02-16 21:18:09
【问题描述】:
我正在尝试通过 Cython 学习如何在 C 和 Python 之间使用回调,并且一直在关注 this demo。我想要一个 Python 函数应用于一个 std::vector/numpy.array 并将结果存储在另一个中。我可以毫无错误地编译和运行,但最终向量 y 是 没有被改变。
C++ 头文件
// callback.hpp
#include<vector>
typedef double (*Callback)( void *apply, double &x );
void function( Callback callback, void *apply, vector<double> &x,
vector<double> &y );
C++源代码
// callback.cpp
#include "callback.hpp"
#include <iostream>
using namespace std;
void function( Callback callback, void* apply,
vector<double> &x, vector<double> &y ) {
int n = x.size();
for(int i=0;i<n;++i) {
y[i] = callback(apply,x[i]);
std::cout << y[i] << std::endl;
}
Cython 标头
# cy_callback.pxd
import cython
from libcpp.vector cimport vector
cdef extern from "callback.hpp":
ctypedef double (*Callback)( void *apply, double &x )
void function( Callback callback, void* apply, vector[double] &x,
vector[double] &y )
Cython 源码
# cy_callback.pyx
from cy_callback cimport function
from libcpp.vector cimport vector
def pyfun(f,x,y):
function( cb, <void*> f, <vector[double]&> x, <vector[double]&> y )
cdef double cb(void* f, double &x):
return (<object>f)(x)
我使用相当样板的设置进行编译:python setup.py build_ext -i
# setup.py
from distutils.core import setup
from distutils.extension import Extension
from Cython.Distutils import build_ext
import numpy
import os
os.environ["CC"] = "g++"
os.environ["CXX"] = "g++"
setup( name = 'callback',
ext_modules=[Extension("callback",
sources=["cy_callback.pyx","callback.cpp"],
language="c++",
include_dirs=[numpy.get_include()])],
cmdclass = {'build_ext': build_ext},
)
最后用 Python 脚本测试
# test.py
import numpy as np
from callback import pyfun
x = np.arange(11)
y = np.zeros(11)
pyfun(lambda x:x**2,x,y)
print(y)
当 y 的元素在 callback.cpp 中设置时,正确的值正在被 打印到屏幕上,这意味着 pyfun 确实被正确评估,但是,在 Python 级别,y 仍然全为零。
知道我做错了什么吗?
【问题讨论】:
标签: python c++ callback cython stdvector