如何在Python中传递数组指针给封装的C++函数
我刚开始接触C++和Python混合编程,对Python/C API还不太了解。最近我开始使用Boost.Python来把一个C++库封装成Python可以用的。现在我遇到问题了,想要封装一个函数,这个函数的参数是一个指向数组的指针。下面是这个函数在C++中的原型。
class AAF{
AAF(AAF_TYPE t);
AAF(double v0, const double * t1, const unsigned * t2, unsigned T);
~AAF();
}
我这样用boost::python封装对吗?
class_<AAF>("AAF", init<AAF_TYPE>())
.def(init<double, const double*, const unsigned*, unsigned>());
注意,我的代码编译和链接都成功了,但我不知道怎么在Python中调用它。我尝试的一些简单方法都失败了。
>>> z = AAF(10, [4, 5.5, 10], [1, 1, 2], 3);
Traceback (most recent call last):
File "./test_interval.py", line 40, in <module>
z = AAF(10, [4, 5.5, 10], [1, 1, 2], 3);
Boost.Python.ArgumentError: Python argument types in
AAF.__init__(AAF, int, list, list, int)
did not match C++ signature:
__init__(_object*, AAF_TYPE)
__init__(_object*, double, double const*, unsigned int const*, unsigned int)
>>> t1 = array.array('d', [4, 5.5, 10])
>>> t2 = array.array('I', [1, 1, 2])
>>> z = AAF(10, t1, t2, 3);
Traceback (most recent call last):
File "./test_interval.py", line 40, in <module>
z = AAF(10, t1, t2, 3);
Boost.Python.ArgumentError: Python argument types in
AAF.__init__(AAF, int, array.array, array.array, int)
did not match C++ signature:
__init__(_object*, AAF_TYPE)
__init__(_object*, double, double const*, unsigned int const*, unsigned int)
我还有第二个问题,我需要封装析构函数吗?请告诉我在某些情况下这是否必要,但并不是总需要。
1 个回答
4
包裹的方式是对的(原则上),但是在
AAF(10, [4, 5.5, 10], [1, 1, 2], 3);
(正如解释器所指出的),你传递给函数的是Python的列表对象,而不是指针。
简单来说,如果你的函数只需要处理Python的列表,你需要修改代码,使用Python的列表接口(而不是指针)。如果你需要保持原来的接口,你就得写一个包装函数,这个函数接收Python的列表,进行适当的转换,然后调用你原来的C++函数。对于numpy数组也是一样的。
请注意,boost::python提供了一些内置机制,可以将Python的容器转换为与STL兼容的容器。
针对你的情况,一个示例包装代码可以是
void f(list o) {
std::size_t n = len(o);
double* tmp = new double[n];
for (int i = 0; i < n; i++) {
tmp[i] = extract<double>(o[i]);
}
std::cout << std::endl;
// use tmp
delete tmp;
}
请查看boost.python的教程,网址是 http://www.boost.org/doc/libs/1_39_0/libs/python/doc/tutorial/doc/html/index.html。