使用 Boost Python 将 Python 列表传递给 C++ 扩展

9
我是一个有用的助手,可以为您翻译文本。

我正在尝试编写一个C++扩展来替换以下Python函数,以加速我的程序。

Python函数如下:

def calc_dist(fea1, fea2):
    #fea1 and fea2 are two lists with same length
    ...

我使用c++和boost python编写了如下的函数:

#include <vector>
#include <boost/python.hpp>
double calc_dist(vector<double>& fea1, vector<double>& fea2)
{
    int len = fea1.size();
    double s=0;
    for(int i=0; i<len;i++){
        double p=fea1[i];
        double q=fea2[i];
        ...//calculating..
    }
    return s;
}
BOOST_PYTHON_MODULE(calc_dist)
{
    using namespace boost::python;
    def("calc_dist",calc_dist);
}

编译上述cpp代码为.so文件,如下所示:

g++ calc_dist.cpp -shared -fPIC -o calc_dist.so -I /usr/include/python2.6 -lboost_python

当我试图在一个Python程序中使用.so文件时,导入操作正常,表明该模块成功地被导入。

然而,每当我将两个列表传递给函数参数时,Python会发生错误,例如:

ArgumentError: Python argument types in
    calc_dist.calc_dist(list, list)
did not match C++ signature:
    calc_dist.calc_dist(std::vector<float, std::allocator<float> >,
                        std::vector<float, std::allocator<float> >)

有谁可以帮我解决这个问题吗?即如何使用boost将Python列表传递给C++扩展程序?

非常感谢!


1
使用boost::python::list 参见 这个问题 - user1356386
1个回答

11

如果你希望函数操作Python列表,为什么要编写一个接受std :: vector的函数呢?它们是不同的东西。

Boost.Python将Python列表公开为list类。

因此,您的函数应该类似于:

double calc_dist(boost::python::list fea1, boost::python::list fea2)
{
    boost::python::ssize_t len = boost::python::len(fea1);
    double s=0;
    for(int i=0; i<len;i++){
        double p = boost::python::extract<double>(fea1[i]);
        double q = boost::python::extract<double>(fea2[i]);
        ...//calculating..
    }
    return s;
}

这个还没有经过测试,但希望足够接近以便您开始使用...


我只是从在线文档中整理了这个例子,所以应该有足够的信息让你取得进展。 - Useless
为什么不自动转换为std::listdeque或其他类型呢?Python列表不是向量,也没有像它们那样的行为。 - Useless
你好,感谢你的有用回答。boost::python::list 的性能如何? - GoingMyWay
可能取决于你对它的使用。像往常一样,最好的建议是尝试并查看结果。 - Useless
通过将其作为自己的问题发布,并包含产生警告所必需的最小代码。这看起来有点像是一个 lambda。 - Useless
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接