Boost python,暴露 meyers 单例

Mar*_*rek 5 c++ python singleton boost

我想以正确的方式去做。我已经看到暴露 boost::serialization::singleton 这里 Boost python export singleton但我不想使用它。我想使用简单的迈耶斯单例来代替。

下面的代码有效,但文档表明使用 http://www.boost.org/doc/libs/1_43_0/libs/python/doc/v2/reference_existing_object.html#reference_existing_object-spec/ 是危险的。

代码:

class Singleton 
{
private:
Singleton(){};

public:
static Singleton & getInstance()
{
    static Singleton instance;
    return instance;
}

int getNumber() { return 5; }
};
Run Code Online (Sandbox Code Playgroud)

并在模块中:

class_<Singleton>("singleton", no_init)
    .def("getInstance", &Singleton::getInstance, return_value_policy<reference_existing_object>()).staticmethod("getInstance")
    .def("getNumber", &Singleton::getNumber)

    ;
Run Code Online (Sandbox Code Playgroud)

有什么好的方法可以做到吗?执行 python 代码时使用return_internal_reference<>()导​​致错误。

Sve*_*ven 4

我们的代码中有很多这样的东西,我没有想到一个简单的方法,但是我们通过使用空删除器从引用中返回 boost::shared_ptr<> 来公开它们(我们以某种方式将部分代码移动到了shared_ptr并且其他则不然,所以这是一个混合物)。这并不是最好的事情,但是如果您确保在离开 main 后不对指针执行任何操作,它会按预期工作并且不会出现任何问题。

对象的生命周期将超过解释器的生命周期,因此在此处将任何引用传递回 python 时不必担心出现任何问题。该库仅在解释器退出后才会释放(可能调用或不调用析构函数,有时可能会出现错误等情况)。因此,在这种情况下,您可以将解释器视为经典的 main() 函数。

class_<XY, shared_ptr<XY>, boost::noncopyable >("XY",no_init)
  .def("getInstance",&XY::getSharedInstance )
  .staticmethod("getInstance")

struct NullDeleter
{
  void operator()(const void*){}
};

XY& XY::getInstance()
{
  static XY in;
  return in;
}

// This can also be written as a standalone function and added to the python class above.
shared_ptr<XY> XY::getSharedInstance()
{
  return shared_ptr<XY>( &getInstance(), NullDeleter() );
}
Run Code Online (Sandbox Code Playgroud)

或者你可以将sharedInstance非侵入式地写入一个单独的函数并在python包中使用它:

shared_ptr<XY> getSharedInstance()
{
  return shared_ptr<XY>( &XY::getInstance(), NullDeleter() );
}

class_<XY, shared_ptr<XY>, boost::noncopyable >("XY",no_init)
  .def("getInstance",&getSharedInstance )
  .staticmethod("getInstance")
Run Code Online (Sandbox Code Playgroud)