C/C++ 代码封装为python 库的技术要点

看了很多关于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参数。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值