В этом случае, я думаю, это зависит от std :: runtime_error.Чтобы клиент мог использовать этот класс, он должен использовать определение, предоставленное на стороне клиента, а не на стороне DLL.Чтобы это было успешным, клиентский компилятор должен быть точно такой же версии, как и компилятор DLL.
И помимо того факта, что определения классов не переносимы через границы модуля, необходимо учитывать и владение памятью.
Если вы наследуете класс, у которого есть внутренняя переменная, такая как std :: string, это будет катастрофа, ожидающая случившегося.Если dll будет использовать среду выполнения, отличную от приложения, в котором другой класс наследует ее, может произойти следующее:
- Base инициализирует строку текстовым значением.
- Производное будетпопытайтесь изменить строку.
- Это попытается освободить память кучи строки.
Конечно, это не ограничивается строками.Это был просто пример.Любой сценарий, в котором одна среда выполнения выделяет что-то, а другая освобождает это, приведет к сбою.
Память кучи принадлежит среде выполнения, используемой базовым классом.Среда выполнения производного класса пытается его освободить -> мгновенный сбой.Вы находитесь в зависимости от провайдера dll, чтобы предоставить вам dll, которая скомпилирована с тем же компилятором C ++ и использует ту же среду выполнения.Это кошмар обслуживания.
Интерфейсы класса DLL, без сомнения, являются худшей идеей.
Единственные 2 исключения:
- вы используете DCOM (или чисто абстрактные классы, что является той же идеей)
- вы контролируете все дерево кода.Например, dll и исполняемый файл встроены в одно и то же решение.
Во всех других случаях интерфейсы класса DLL поддерживают ночные кошмары, а бедствия ожидают.
Я думаю этот поток может предложить вам решение.
Не стесняйтесь игнорировать C4275, если вы компилируете все с помощью одного и того же компилятора и используете /MD
, поэтому все модули имеют одинаковое время выполнения.