Как лучше реализовать API для модулей?

Ситуация такова: есть EXE и DLL, которую этот исполняемый файл должен загружать. В этом DLL должны использоваться классы из EXE.
Так вот как мне дать DLL эту возможность? Конечно, C++ может вызвать виртуальные методы у указателей, но как быть с конструкторами и деструкторами классов?
  • Вопрос задан
  • 180 просмотров
Решения вопроса 1
Nipheris
@Nipheris Куратор тега C++
> Конечно, C++ может вызвать виртуальные методы у указателей
именно, поэтому вам нужно, как вариант:
1) сделать абстрактные интерфейсы вроде IFooService, библиотека будет отдавать указатели на объекты, их реализующие
2) сделать функции-фабрики и функции-уничтожители:
IFooService* CreateFooService(...);
void DestroyFooService(IFooService* service);

Это все нужно в частности для того, чтобы управление памятью не выходило за пределы DLL - иными словами, где порождается, там и убивается. Для большинства библиотек это приемлемое ограничение, которое позволяет сохранять ABI и даже использовать разные рантаймы для DLL и для EXE, его использующего.
Если вы будете передавать какие-то параметры по указателю, также следуйте этому правилу - не делайте так, что код в EXE выделяет память, а код в DLL - освобождает, и наоборот.
Ну и вообще, это хорошая абстракция интерфейса (ваш IFooService) от реализации (ваш конкретный класс FooService с конкретным конструктором и деструктором. К-р и д-р сложного класса должны оставаться частью _реализации_).
Если в качестве параметров, передающихся по значению вы используете struct-ы, это вполне допустимо, но тогда уже надо компилировать DLL и EXE одним компилятором, как этого требует, например, Qt (игнорирование этого правила рано или поздно приведет к странным и трудноуловим ошибкам, связанным с тем, что разные версии компилятора генерируют разный код конструкторов и деструкторов, и вообще могут по разному разложить struct в памяти).
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
heksen
@heksen
Сделайте класс импорта с виртуальными функциями. И загружайте в него его реализацию через LoadLibrary.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы