首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >无法从python C++包装器访问析构函数

问无法从python C++包装器访问析构函数
EN

Stack Overflow用户
提问于 2015-11-09 09:00:28
回答 1查看 345关注 0票数 3

我正在尝试将一些现有的C++函数封装到python中。我将问题简化为下面列出的代码:

代码语言:javascript
复制
#include <boost/python.hpp>

class A { ~A( ); };
void func( const A& );

int main( int argc, char** argv ){
    boost::python::def( "func", func );
}

在我的情况下,访问私有析构函数A::A.注意,A::A必须是不可访问的,而且我不能修改现有的C++代码。如果函数得到指针而不是引用,上面的示例将编译Note2。

代码语言:javascript
复制
void func( const A* );

我想解释一下boost::python,在我的例子中,它不能删除对象A。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-11-30 03:30:26

实现这一目标的一种方法是使用一个接受A*并委托给func(const A&)的辅助函数。

代码语言:javascript
复制
boost::python::def("func", +[](A* a) { return func(*a); });

当一个函数通过boost::python::def()直接公开时,Boost.Python将尝试注册转换器,以获取在语言屏障之间传递的参数。为了减少挂起引用的可能性,Python将对任何非指针参数进行附带值转换。通过使用辅助性,在函数分派期间将使用from-Python指针转换器.

下面是一个完整的示例示范,它使用一个辅助函数来避免附带值转换.它还展示了如何使用boost::shared_ptr显式自定义通过Boost.Python公开的类的销毁:

代码语言:javascript
复制
#include <boost/python.hpp>
#include <boost/shared_ptr.hpp>

namespace {
int func_count = 0;
} // namespace

// Legacy model.
class spam
{
private:
  ~spam() {};
};

// Legacy API.
void func(const spam&)
{
  ++func_count;
};

/// @brief Factory function to create Spam instances with
///        a custom deleter.
boost::shared_ptr<spam> make_spam()
{
  // Create a new spam instance with a no-op deleter.
  auto no_op = +[](void*) {};
  return boost::shared_ptr<spam>(new spam(), no_op);
}

BOOST_PYTHON_MODULE(example)
{
  namespace python = boost::python;
  // Expose class A with a custom deleter.
  python::class_<spam, boost::shared_ptr<spam>,
      boost::noncopyable>("Spam", python::no_init)
    .def("__init__", python::make_constructor(&make_spam))
    ;

  // Use an auxiliary function to avoid by-value conversion 
  // at the language boundary.  This prevents Boost.Python 
  // from creating instance holders that would hold the value
  // as an rvalue.
  python::def("func", +[](spam* spam){ return func(*spam); });

  python::def("get_count", +[]() { return func_count; });
}

互动用法:

代码语言:javascript
复制
>>> import example
>>> spam = example.Spam()
>>> assert(0 == example.get_count())
>>> example.func(spam)
>>> assert(1 == example.get_count())
>>> try:
...     example.func(1)
...     assert(False)
... except TypeError:
...     pass
... 
>>> assert(1 == example.get_count())

请注意,在上面的示例中,spam实例由具有自定义删除器的boost::shared_ptr管理,该删除器不删除实例。当一个对象不再被Python或C++引用时,这个钩子允许自定义策略调用。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/33605556

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档