使手柄可从两侧闭合

时间:2018-12-10 10:03:02

标签: shared-ptr handle c++98

我有一个声音驱动程序/播放器界面,其功能类似于SoundHandle Load(bfs::path)void Play(SoundHandle)。实现以插件/共享库的形式提供

这个想法是:通过带有最小接口的手柄返回加载的声音。如果此手柄被破坏,声音将被卸载。卸载插件后,所有句柄都将失效。

我的实现使用shared_ptr和这样的自定义删除器:

/// Base class for a sound descriptor managed by the driver
struct SoundDesc : boost::noncopyable
{
    virtual ~SoundDesc() {}
    bool isValid() const { return isValid_; }

protected:
    explicit SoundDesc() : isValid_(true) {}
    bool isValid_;
};
class SoundHandle
{
public:
    typedef boost::shared_ptr<SoundDesc> Descriptor;

    explicit SoundHandle(Descriptor descriptor = Descriptor()) : descriptor_(descriptor) {}
    /// Return true if the sound is still valid/loaded
    bool isValid() const { return (!descriptor_) ? false : descriptor_->isValid(); }
    /// Function for the driver to query the descriptor
    const Descriptor& getDescriptor() const { return descriptor_; }

private:
    Descriptor descriptor_;
};

然后创建的是:

SoundHandle AudioDriver::CreateSoundHandle(SoundDesc* sound)
{
    sounds_.push_back(sound);
    namespace bl = boost::lambda;
    using bl::_1;
    return SoundHandle(
      SoundHandle::Descriptor(sound, bl::if_(bl::bind(&SoundDesc::isValid, _1))
                                       bl::bind(&AudioDriver::UnloadSound, boost::ref(*this), _1)]
                                       .else_[bl::bind(bl::delete_ptr(), _1)]));
}

这是插件基类中的通用代码,具体类使用指向SoundDesc的实现特定子类的指针(例如,保存自定义数据)来调用此代码(例如,保存自定义数据)AudioDriver::UnloadSound是一种静态方法,其名称应为所建议的

这很好用,但是当在所有SoundHandles之前卸载插件时,我在shared_ptr的dtor中遇到了分段错误。看来lambda生成的代码位于共享库的空间中,并且在卸载时消失了,剩下的只是悬空的指针。

如何解决?

我唯一的想法是让SoundHandle存储一个weak_ptr和驱动程序shared_ptrs,因此,当soft_ptr已经为0时,它不会调用该插件代码。但这将使声音的生命周期等于该插件的生命周期,尽管声音可能不再使用。

0 个答案:

没有答案