赞
踩
看了很多关于C/C++代码封装为python库的文章,大多太过粗浅,离工程实施有较大差距。现结合国外资料和摸索成果记录如下:
1)SWIG可以自动将C代码转换为python的pyd库,但是对于回调和C语言大多参数类型的转换还未做到全自动化,有大量的工作要做;
2) boost.python帮我们作了很多转换的工作,但技术支持匮乏,用好不容易。下面列举其中的几个技术要点:
*) C语言函数中多个参数返回值做转换到python 采用return boost::python::make_tuple(ret1,ret2,。。。);
*)C语言回调PYTHON函数可以借助一个封装类py_callable
class with_gil
{
public:
with_gil() { state_ = PyGILState_Ensure(); }
~with_gil() { PyGILState_Release(state_); }
with_gil(const with_gil&) = delete;
with_gil& operator=(const with_gil&) = delete;
private:
PyGILState_STATE state_;
};
class py_callable
{
public:
/// @brief Constructor that assumes the caller has the GIL locked.
py_callable(const boost::python::object& object)
{
with_gil gil;
object_.reset(
// GIL locked, so it is safe to copy.
new boost::python::object{object},
// Use a custom deleter to hold GIL when the object is deleted.
[](boost::python::object* object)
{
with_gil gil;
delete object;
});
}
// Use default copy-constructor and assignment-operator.
py_callable(const py_callable&) = default;
py_callable& operator=(const py_callable&) = default;
template <typename ...Args>
void operator()(Args... args)
{
// Lock the GIL as the python object is going to be invoked.
with_gil gil;
(*object_)(std::forward<Args>(args)...);
}
private:
std::shared_ptr<boost::python::object> object_;
};
py_callable* p_callback1=NULL;
py_callable* p_callback2=NULL;
.。。。
setcallback(pc1,pc2);//这里写个函数把pc1赋值给p_callback1,把pc2赋值给p_callback2,pc1、pc2分别是python的def函数对象;
p_callback1(arg1,arg2,......) ;//对应python 的def 函数
*)采用boost::python::object 传入python函数和python参数。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。