gpt4 book ai didi

python - 通过 Cython(回调)将 Python 函数应用于 std::vector

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:29:09 27 4
gpt4 key购买 nike

我正在尝试学习如何通过 Cython 在 C 和 Python 之间使用回调,并且一直在查看 this demo .我想要一个 Python 函数应用于一个 std::vector/numpy.array 并将结果存储在另一个中。我可以毫无错误地编译和运行,但最终 vector 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;
}

赛通头文件

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

赛通源码

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

当在 callback.cpp 中设置 y 的元素时,正确的值被打印到屏幕上,这意味着 pyfun 确实被正确评估,但是,在 Python 级别,y 仍然全为零。

知道我做错了什么吗?

最佳答案

谢谢,伊恩。根据您的建议,我更改了代码以返回一个 vector ,而不是尝试就地修改它。这行得通,虽然公认不是特别有效

回调.hpp

 typedef double (*Callback)( void *apply, double x );

vector<double> function( Callback callback, void *apply,
const vector<double> &x );

回调.cpp

vector<double> function( Callback callback, void* apply, 
const vector<double> &x ) {

int n = x.size();
vector<double> y(n);

for(int i=0;i<n;++i) {
y[i] = callback(apply,x[i]);
}
return y;
}

cy_callback.pxd

cdef extern from "callback.hpp":
ctypedef double (*Callback)( void *apply, const double &x )

vector[double] function( Callback callback, void* apply,
vector[double] &x )

cy_callback.pyx

from cy_callback cimport function
from libcpp.vector cimport vector

def pyfun(f,x):
return function( cb, <void*> f, <const vector[double]&> x )


cdef double cb(void* f, double x ):
return (<object>f)(x)

测试.py

import numpy as np
from callback import pyfun

x = np.arange(11)
y = np.zeros(11)

def f(x):
return x*x

y = pyfun(f,x)
print(y)

关于python - 通过 Cython(回调)将 Python 函数应用于 std::vector,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28550511/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com