当前位置:   article > 正文

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

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参数。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小丑西瓜9/article/detail/555650
推荐阅读
相关标签
  

闽ICP备14008679号