使用 cython 向 python 公开一个 c++ 函数

Posted

技术标签:

【中文标题】使用 cython 向 python 公开一个 c++ 函数【英文标题】:Exposing a c++ function to python using cython 【发布时间】:2016-04-27 19:54:18 【问题描述】:

我正在尝试,如下所示:

from libcpp.vector cimport vector

cdef extern from "auction.h":
    cpdef double util(
        int q, 
        int sq, 
        double alpha, 
        double beta, 
        double kappa, 
        int s, 
        int ss, 
        int m, 
        const vector[double]& p, 
        double a0);

我收到以下(不是很详细的)错误:

src\RFQLib.pyx:4:21: 无法转换 'double (int, int, double, double, double, int, int, int, const vector[double] &, double)' 到 Python 对象

这里有什么问题?

提前感谢您的所有帮助。

【问题讨论】:

您可以尝试将p的类型从const vector[double]&更改为列表、元组或numpy数组,然后根据需要转换为const vector[double]& 【参考方案1】:

您必须首先告诉 Cython 该函数(通过cdef exetern from 机制),然后创建一个调用它的 Cython 函数,您可以在 Python 中使用它:

from libcpp.vector cimport vector

cdef extern from "auction.h":
    double util(
        int q, 
        int sq, 
        double alpha, 
        double beta, 
        double kappa, 
        int s, 
        int ss, 
        int m, 
        const vector[double]& p, 
        double a0);

def py_util(int q, 
        int sq, 
        double alpha, 
        double beta, 
        double kappa, 
        int s, 
        int ss, 
        int m, 
        p, 
        double a0):
    cdef vector[double] p_vec = p
    return util(q,sq,alpha,beta,kappa,s,ss,m,p_vec,a0)

稍微复杂的是转换为 C++ vector<double>。 Cython 可以自动将包含适当类型的列表/元组转换为向量。另一方面是每次你调用py_util 时都会这样做,所以可能有点慢。如果util 存储引用以供以后使用(可能不太可能,但总是有可能!),这也是一个问题,因为到那时p_vec 将不复存在。

另外两个选项是创建一个包装 vector[double] 的 Cython 类。这显然对您来说需要做更多的工作,但可以避免每次调用 py_util 时进行类型转换。或者,您可以修改util,使其使用double*,并在Python 端使用numpy 数组或python 数组。

【讨论】:

以上是关于使用 cython 向 python 公开一个 c++ 函数的主要内容,如果未能解决你的问题,请参考以下文章

Boost.python vs Cython 用于 C++/python 接口

使用现有 C 对象初始化 Cython 对象

如何使用 cython 将 python 类公开给 c++

如何在 Cython 中返回新的 C++ 对象?

如何最好地将 C++/Cython 项目编译成可执行文件?

如何从 cython 公开静态 constexpr