0

I've been using Boost in a DLL project but didn't export any Boost dependencies ...yet. Just C-Types and things which derive from the DLL Source tree itself.

But now I'm struggling with a lockable data model... I cannot get it designed exception safe and do not direct export boost types to the DLL interface.

struct DLL_EXPORT DllTestData {
    double test1;
    double test2;

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

    boost::mutex;
}

And use it:

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

One could at least design probably some sort of DllTestData::Pimpl and hide the mutex type from the Dll. But If I want to use it like this:

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

While writing this I'm beginning to think about a ILockable-Interface and hide the mutex type in a PImpl or some sort, so something like this:

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();
    }
}

And use it like this:

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

Would this be a valid approach (hide mutex type with a pimpl and work with an Lockable interface) or am I going in the wrong direction with this? Or what would work better in this scenario? Maybe move the entire boost::mutex PImpl to the Interface?

4

1 回答 1

0

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

再看一遍,您可以完全避免暴露互斥锁。例如,如果一次只设置两个值,则公开一个

void setValues(double test1,double test2);

在方法中,您可以自己设置互斥锁。或者如果您不想要一个大的获取和设置列表,则可以使用更经典的 Win32 方法:公开一个没有任何方法的结构,例如:

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

并将函数或方法添加到您的导出中,例如

void setTestData(DLLTestData value);

在您的库中,您可以锁定和 memcpy 整个结构。如前所述,在大量使用 Win32 API 的过程中,我习惯了第二种方式,但我个人更喜欢第一种方式,带有接口和 get/setter,即使它需要更多的努力。

于 2013-09-01T14:36:21.260 回答