Python 使用C/API和C++;班级
我对编写定制Python模块的业务还不熟悉,我对胶囊的工作原理有点困惑。我使用SystemOSX安装中的Python2.7.6,并尝试使用胶囊(对于Python>2.7推荐)来传递指针(在使用PycoObject之前)。我的代码目前不起作用,我想了解一下在这里原则上应该如何处理事情。代码应该定义一个类LuscherClm,我希望能够执行以下操作:Python 使用C/API和C++;班级,python,c++,c,module,Python,C++,C,Module,我对编写定制Python模块的业务还不熟悉,我对胶囊的工作原理有点困惑。我使用SystemOSX安装中的Python2.7.6,并尝试使用胶囊(对于Python>2.7推荐)来传递指针(在使用PycoObject之前)。我的代码目前不起作用,我想了解一下在这里原则上应该如何处理事情。代码应该定义一个类LuscherClm,我希望能够执行以下操作: >>> c40=Luscher(4,0) >>> >>> c40(0.12) >>&
>>> c40=Luscher(4,0)
>>>
>>> c40(0.12)
>>> <print the result of the evaluation>
因此,我的第一个问题是:如何修改方法表,使其具有更多运算符样式转换,而不是成员函数init和eval
<>但是,我的代码还有其他问题,这里是相关的部分(基础C++类工作顺利,我在生产中经常用到):
析构函数:
//destructor
static void clm_destruct(PyObject* capsule){
void* ptr=PyCapsule_GetPointer(capsule,"zetfunc");
Zetafunc* zetptr=static_cast<Zetafunc*>(ptr);
delete zetptr;
return;
}
你能给我解释一下什么是错的以及为什么吗?如果可能的话,我想远离SWIG或boost,因为这个模块应该很容易移植,并且我想避免每次我想在其他地方使用它时都必须安装额外的软件包。
进一步:C/API在调用函数时产生的开销是多少?我需要称之为O(10^6)次,我仍然希望它是快速的
好的,我现在正在使用boost.python,但是当我运行object.eval()时,我得到了一个segfault。这就是我现在的程序:
BOOST_PYTHON_MODULE(threevecd)
{
class_< threevec<double> >("threevecd",init<double,double,double>());
}
BOOST_PYTHON_MODULE(LuscherClm)
{
class_<Zetafunc>("LuscherClm",init<int,int, optional<double,threevec<double>,double,int> >())
.def("eval",&Zetafunc::operator(),return_value_policy<return_by_value>());
boost::python::to_python_converter<dcomplex,dcomplex_to_python_object>();
}
BOOST_PYTHON_模块(threevecd)
{
类(thireevec>(“thireevecd”,init());
}
BOOST_PYTHON_模块(LuscherClm)
{
类(“LuscherClm”,init())
.def(“eval”,&Zetafunc::operator(),return_value_policy());
boost::python::to_python_converter();
}
dcomplex是我自己的复数实现。所以我不得不写一个转换器:
struct dcomplex_to_python_object
{
static PyObject* convert(dcomplex const& comp)
{
if(fabs(comp.im())<std::numeric_limits<double>::epsilon()){
boost::python::object result=boost::python::object(complex<double>(comp.re(),comp.im()));
return boost::python::incref(result.ptr());
}
else{
return Py_BuildValue("d",comp.re());
}
}
};
struct dcomplex\u to\u python\u对象
{
静态PyObject*转换(dcomplex const&comp)
{
如果(fabs(comp.im())正常,我得到了它。以下转换器执行此任务:
struct dcomplex_to_python_object
{
static PyObject* convert(dcomplex const& comp)
{
PyObject* result;
if(std::abs(comp.im())<=std::numeric_limits<double>::epsilon()){
result=PyFloat_FromDouble(comp.re());
}
else{
result=PyComplex_FromDoubles(comp.re(),comp.im());
}
Py_INCREF(result);
return result;
}
};
struct dcomplex\u to\u python\u对象
{
静态PyObject*转换(dcomplex const&comp)
{
PyObject*结果;
如果(std::abs(comp.im())没问题,因为我到目前为止没有收到任何响应,而且我真的不喜欢API文档,我想使用boost.python。然而,它似乎比我想象的要复杂。这就是我现在的全部方法:boost_python_模块(threevecd){class(“threevecd”,init();}boost_python_模块(LuscherClm){class((“LuscherClm”,init()).def(“eval”,&Zetafunc::operator(),return_value_policy());boost::python::to_python_converter()}在python中,在构造实例后会调用uu init_uu(),这意味着您可以毫无问题地使用“self”,因为它是一个有效的对象(尽管尚未初始化)此时.re.直接调用实例:我想您会想填充tp_调用槽(python中的_ucall_uu())。好的,谢谢。但是我如何解决segfault问题呢?理想的情况是在python中返回一个复数。您尝试过Py_complex
类型吗?
PyMODINIT_FUNC
initLuscherClm(void)
{
PyObject *m = Py_InitModule("LuscherClm", LuscherClmMethods);
return;
}
BOOST_PYTHON_MODULE(threevecd)
{
class_< threevec<double> >("threevecd",init<double,double,double>());
}
BOOST_PYTHON_MODULE(LuscherClm)
{
class_<Zetafunc>("LuscherClm",init<int,int, optional<double,threevec<double>,double,int> >())
.def("eval",&Zetafunc::operator(),return_value_policy<return_by_value>());
boost::python::to_python_converter<dcomplex,dcomplex_to_python_object>();
}
struct dcomplex_to_python_object
{
static PyObject* convert(dcomplex const& comp)
{
if(fabs(comp.im())<std::numeric_limits<double>::epsilon()){
boost::python::object result=boost::python::object(complex<double>(comp.re(),comp.im()));
return boost::python::incref(result.ptr());
}
else{
return Py_BuildValue("d",comp.re());
}
}
};
struct dcomplex_to_python_object
{
static PyObject* convert(dcomplex const& comp)
{
PyObject* result;
if(std::abs(comp.im())<=std::numeric_limits<double>::epsilon()){
result=PyFloat_FromDouble(comp.re());
}
else{
result=PyComplex_FromDoubles(comp.re(),comp.im());
}
Py_INCREF(result);
return result;
}
};