Что безопасно для системы подключаемых модулей C ++?

StackOverflow https://stackoverflow.com/questions/43322

Вопрос

Системы подключаемых модулей на C ++ сложны, потому что ABI не определен должным образом, и каждый компилятор (или его версия) следует своим собственным правилам.Однако COM в Windows показывает, что можно создать минимальную систему подключаемых модулей, которая позволяет программистам с различными компиляторами создавать подключаемые модули для хост-приложения, используя простой интерфейс.

Давайте будем практичными и оставим на минутку стандарт C ++, который не очень полезен в этом отношении.Если я хочу написать приложение для Windows и Mac (и, возможно, Linux), поддерживающее подключаемые модули C ++, и если я хочу предоставить авторам подключаемых модулей достаточно большой выбор компиляторов (скажем, версии Visual C ++, GCC или компилятора Intel C ++ менее 2-летней давности), на какие функции C ++ я мог бы рассчитывать?

Конечно, я предполагаю, что плагины будут написаны для конкретной платформы.

Навскидку, вот некоторые функции C ++, о которых я могу подумать, и то, что я считаю ответом:

  • макет vtable для использования объектов через абстрактные классы?(да)
  • встроенные типы, указатели?(да)
  • структуры, союзы?(да)
  • исключения?(нет)
  • внешние функции "C"?(да)
  • stdcall - это не внешние функции "C" со встроенными типами параметров?(да)
  • не-stdcall не-внешние функции "C" с определяемыми пользователем типами параметров?(нет)

Я был бы признателен за любой опыт, который у вас есть в этой области, которым вы могли бы поделиться.Если вы знаете какое-нибудь умеренно успешное приложение, в котором есть система подключаемых модулей C ++, это тоже здорово.

Карл

Это было полезно?

Решение

В журнале доктора Добба есть статья Создание вашего собственного фреймворка плагинов:Часть 1 это довольно хорошее чтение на эту тему.Это начало серии статей, посвященных архитектуре, разработке и развертыванию кроссплатформенной платформы плагинов на C / C ++.

Другие советы

Возможно, вы также захотите рассмотреть возможность замены обычного интерфейса плагина скриптовым интерфейсом.В C / C ++ есть несколько очень хороших привязок для нескольких языков сценариев, которые уже решили вашу проблему.Возможно, было бы неплохо построить что-то поверх них.Например, взгляните на Boost.Python.

Qt имеет очень хорошую систему для плагинов, которую я использовал в прошлом.Он использует систему метаобъектов Qt для преодоления многих проблем, обычно возникающих при попытке разработки плагинов для C ++.

Одним из примеров является то , как Q_DECLARE_INTERFACE работает, чтобы предотвратить использование вами несовместимого плагина.Другой - это ключ сборки, чтобы убедиться, что вы загрузили правильный плагин для вашей архитектуры, операционной системы, компилятора.Если вы не используете систему плагинов Qt, вам придется беспокоиться об этих вещах и придумывать решения самостоятельно.Это не обязательно ракетостроение, и я не говорю, что у вас ничего не получится, но ребята из Trolltech довольно умны и потратили некоторое время на размышления об этом, и я бы предпочел использовать то, что они создали, чем изобретать велосипед самому.

Другим примером является то, что RTTI обычно это не работает за пределами библиотеки DLL, но при использовании Qt такие вещи, как qobject_cast (объект_каст) которые полагаются на систему метаобъектов, работают вне границ DLL.

Я думаю, вы в безопасности, создавая систему плагинов, основанную на:

  • Упаковка функциональности плагина в библиотеку (.dll, .so и т.д.)
  • Требование, чтобы плагин предоставлял доступ к ключевому экспорту на C-язык.
  • Требование, чтобы плагин реализовывал (и возвращал указатель / ссылку на) абстрактный интерфейс C ++.

Вероятно, самая успешная система плагинов для C ++:старый добрый Adobe Photoshop.А если не это, то один из виртуальных синтезаторных форматов, таких как VSTi и т.д.

Книга Несовершенный C ++ Мэтью Уилсона есть хорошая информация по этому поводу.

Совет, содержащийся, по-видимому, в:пока вы используете тот же (или эквивалентный) компилятор, вы можете использовать C ++, в противном случае вам лучше использовать C в качестве интерфейса поверх вашего кода на C ++.

туз имеет кроссплатформенную архитектуру подключаемых модулей.

Проверьте:

  1. ACE DLL
  2. Менеджер DLL ACE

Я бы посоветовал ознакомиться с этой книгой
Руководство для программиста ACE

Firefox работает на XPCOM (http://www.mozilla.org/projects/xpcom/).Он вдохновлен Microsoft COM, но он мультиплатформенный.

У меня есть свой собственный игровой движок с подключаемой системой C ++.

У меня есть некоторый код в заголовочных файлах, поэтому он помещается в модуль компиляции плагина.

Более крупные функции, которые находятся в основном движке, вызываются через экспортированную функцию C (плагин вызывает MyObject_somefunction(MyObject * obj), которая в движке просто вызывает obj-> somefunction()).Если вызов функции C на ваш вкус уродлив, то с помощью некоторой хитрости с заголовком, когда заголовок включен в плагин, определите функцию-член # для вызова функции C.:

#if defined(IN_THE_PLUGIN)
void MyObject::somefunction() { MyObject_somefunction(this); }
#endif

Виртуальные функции либо должны быть чистыми, либо код должен находиться в заголовочном файле.Если я не наследую от класса, а просто создаю экземпляр одного, код виртуальной функции может находиться в движке, но тогда класс должен экспортировать некоторые функции C для создания и уничтожения объекта, который вызывается из плагина.

По сути, приемы, которые я использовал с целью поддержания полной независимости от платформы, сводятся всего лишь к экспорту C и трюкам с заголовочными файлами.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top