Какой самый простой способ написать переносимые динамически загружаемые библиотеки на C ++? - PullRequest
6 голосов
/ 25 августа 2010

Я работаю над проектом, в котором есть несколько похожих путей кода, которые я хотел бы отделить от основного проекта в плагины. Проект должен оставаться кросс-платформенным, и все API-интерфейсы динамической загрузки библиотек, на которые я обращался, зависят от платформы.

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

Спасибо.

Ответы [ 4 ]

7 голосов
/ 25 августа 2010

Вам потребуется использовать зависимый от платформы код для системы загрузки . Загрузка DLL в Windows отличается от загрузки общего объекта в Unix. Но с парой #ifdef вы сможете иметь в основном загрузчик с одинаковой базой кода.

Сказав это, я думаю, вы можете сделать вашу платформу плагинов независимой. Конечно, вам придется скомпилировать его для каждой платформы, но код будет на 99% одинаковым.

5 голосов
/ 25 августа 2010

Динамическая библиотека, загружающая Windows и Unix / Linux, работает с 3 функциями.Пара функций для загрузки / выгрузки библиотек и другая функция для получения адреса функции в библиотеке.Вы можете легко написать оболочку для этих трех функций, чтобы обеспечить поддержку кросс-операционных систем.

4 голосов
/ 25 августа 2010

В идеале, я хотел бы написать один плагин, и он будет работать на всех операционных системах, поддерживаемых проектом.

Несколько вещей из головы:

  • Избегайте статических объектов в динамических библиотеках. Обеспечить правильные методы / функции инициализации для выделения объектов. Проблемы, возникающие при загрузке библиотеки ОС (это происходит при вызове c-cors для статических объектов), очень трудно отлаживать - только после проблем с многопоточностью.

  • Заголовки интерфейса могут не содержать код. Нет встроенных методов, никакой препроцессор не определяет. Это делается для того, чтобы не испортить приложение кодом из определенной версии библиотеки, что делает невозможным его замену в более позднее время.

  • Заголовки интерфейса не могут содержать сами классы реализации - только абстрактные классы и фабричные функции . Аналогично предыдущему пункту - избегать применения зависит от конкретной версии классов. Фабрики необходимы для того, чтобы пользовательское приложение могло создавать конкретные классы реализации.

  • При представлении новой версии интерфейса, для обеспечения обратной совместимости, не изменяйте существующий абстрактный класс - создайте новый абстрактный класс, унаследованный от него, и добавьте туда новые методы. Измените фабрику, чтобы вернуть новую версию. (Вспомните IInterface MS, IInterface2, IInterface3 и т. Д.) В реализации используйте более новую версию абстрактного класса. Это благодаря полиморфизму сделает реализацию обратно совместимой со старыми версиями интерфейса. (Это, очевидно, требует периодического обслуживания интерфейса и очистки - для удаления старого мусора.)

2 голосов
/ 25 августа 2010

Взгляните на библиотеку boost.extension, в действительности она не является частью boost, но вы можете найти ее в песочнице.Он также немного заморожен, но в целом библиотека стабильна и проста в использовании.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...