Скрыть Boost :: mutex из интерфейса DLL из блокируемого контейнера

Я использовал Boost в проекте DLL, но не экспортировал какие-либо зависимости Boost … пока. Просто C-типы и вещи, которые происходят от самого дерева исходного кода DLL.

Но сейчас я борюсь с блокируемой моделью данных … Я не могу создать безопасную исключительную ситуацию и не направлять типы повышения экспорта в интерфейс 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-Интерфейс и скрыть тип mutex в 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 и работать с Lockable интерфейс) или я иду в неправильном направлении с этим? Или что будет работать лучше в этом сценарии? Может быть, переместить весь boost :: mutex PImpl в интерфейс?

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

внутри вашей библиотеки вы можете заблокировать и запомнить всю структуру. Как было сказано ранее, я привык ко второму способу при интенсивном использовании Win32 API, но лично я предпочитаю первый подход с интерфейсом и get / setter, даже если это требует больше усилий.

0

Другие решения

Других решений пока нет …