我一直在DLL项目中使用Boost,但没有导出任何Boost依赖项...yet。只有从DLL源树本身派生出来的C类型和东西。
但现在我在挣扎于一个可锁定的数据模型..。我无法获得它设计的异常安全,也不直接导出助推类型到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-Interface,并将互斥类型隐藏在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移动到接口上?
发布于 2013-09-01 14:36:21
是的,在我看来,你走在正确的轨道上。但是,您的结构太“重”了,所以应该将其导出为一个接口,使用的是值的get和set方法,而不是值本身。如果您使用工厂模式,一个用于创建对象的函数和一个用于删除的函数,您可以安全地从dll内的接口中派生,而无需公开讨厌的Pimpl * impl。
再看看它,你就可以避免暴露互斥体了。例如,如果应该同时设置两个值,则公开
void setValues(double test1,double test2);在方法中,您可以自己设置互斥对象。或者更经典的Win32方法,如果您不想要一个大的get和set列表:公开一个没有任何方法的结构,比如:
struct DLLTestData
{
double test1;
double test2;
// …and as many as you want
};并向导出中添加一个函数或方法,如下
void setTestData(DLLTestData value);在您的库中,您可以锁定和记忆整个结构。如前所述,在大量使用Win32 API期间,我已经习惯了第二种方法,但我个人更喜欢使用接口和get/setter的第一种方法,即使这需要更多的努力。
https://stackoverflow.com/questions/18537010
复制相似问题