我是C ++ / Python混合语言编程的新手,对Python / C API并不了解。我刚开始使用Boost.Python来包装Python的C ++库。我被困在包装一个函数,该函数将指向数组的指针作为参数。以下(第二个ctor)是它在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)
我的第二个问题是我是否还需要包装析构函数?请说明在某些情况下是否有必要,但并非总是如此。
答案 0 :(得分:4)
包装是正确的(原则上),但在
AAF(10, [4, 5.5, 10], [1, 1, 2], 3);
(正如解释器指出的那样)你传递给你的函数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;
}
请查看http://www.boost.org/doc/libs/1_39_0/libs/python/doc/tutorial/doc/html/index.html上的boost.python教程。