从可锁定容器中的DLL接口隐藏Boost :: mutex

时间:2013-08-30 15:53:27

标签: c++ boost dll mutex boost-mutex

我一直在DLL项目中使用Boost但是没有导出任何Boost依赖项......只是C-Types和源自DLL Source树本身的东西。

但现在我正在努力使用可锁定的数据模型......我无法将其设计为异常安全,并且不会将导出类型直接导入DLL接口。

struct DLL_EXPORT DllTestData {
    double test1;
    double test2;

    void lock();
    void unlock();
    DllTestDataLock getGuard();

    boost::mutex;
}

并使用它:

DllTestData ptr;
ptr->lock();
ptr->test1 = 1.0;
ptr->unlock(); 

至少可以设计某种 DllTestData :: Pimpl 并隐藏Dll中的互斥锁类型。但如果我想这样使用它:

DllTestData ptr;
{
    auto g = ptr->getGuard();
    ptr->test1 = 1.0;
}

在写这篇文章的时候,我开始考虑 ILockable - 接口,并在PImpl或某种类型中隐藏互斥锁类型,所以像这样:

struct ILockable {
    void lock() = 0;
    void unlock() = 0;
}

struct DLL_EXPORT DllTestData : public struct ILockable {
    /// ...
private:
    class PImpl;
    Pimpl * impl;
}

struct Guard {
    Guard( ILockable * ptr ) {
        ptr->lock();
    }
    ~Guard() {
        ptr->unlock();
    }
}

并像这样使用它:

DllTestData ptr = fromDll();
{
    Guard g(ptr);
    ptr->test1 = 1.0;
}

这是一种有效的方法(使用pimpl隐藏互斥锁类型并使用可锁定的界面)或者我是否朝这个方向走错了?或者在这种情况下哪些更好?也许将整个boost :: mutex PImpl移动到接口?

1 个答案:

答案 0 :(得分:0)

是的,在我看来,你走在正确的轨道上。但是你的结构是如此“沉重”,你应该将它作为一个接口使用值的get和set方法而不是值本身。如果你使用工厂模式,一个用于创建对象的函数和一个用于删除的函数可以安全地从你的dll中的接口派生,甚至不暴露令人讨厌的Pimpl * impl。

再看一下,你可以避免暴露互斥锁。例如,如果只应同时设置两个值,则公开

void setValues(double test1,double test2);

在methode中,您可以自己设置互斥锁。或者更经典的Win32方法,如果你不想要一个大的get和set列表: 使用以下任何方法公开结构:

struct DLLTestData
{
double test1;
double test2;
// …and as many as you want 
};

并为您的导出添加功能或方法,如

void setTestData(DLLTestData value);
在您的库中,您可以锁定并记忆整个结构。如前所述,我习惯于在大量使用Win32 API时采用第二种方式,但我个人更喜欢使用接口和get / setter的第一种方法,即使它需要更多的努力。