I ' Я работаю над проектом, в котором есть несколько похожих путей кода, которые я хотел бы отделить от основного проекта в плагины. Проект должен оставаться кросс-платформенным, и все API-интерфейсы динамической загрузки библиотек, на которые я обращался, зависят от платформы.
Какой самый простой способ создать динамическую систему загрузки библиотек, которую можно компилировать и запускать в нескольких операционных системах? без дополнительной модификации кода? В идеале я хотел бы написать один плагин и заставить его работать на всех операционных системах, которые поддерживает проект.
Спасибо.
Вам нужно будет использовать код, зависящий от платформы, для системы загрузки . Загрузка библиотеки DLL в Windows отличается от загрузки общего объекта в Unix. Но с парочкой #ifdef
вы сможете иметь в основном такую же базу кода в загрузчике.
Сказав это, я думаю, вы можете сделать свои плагины независимыми от платформы. Конечно, вам придется скомпилировать его для каждой платформы, но код будет на 99% одинаковым.
В идеале я бы хотел написать один плагин, и он работал бы во всех операционных системах, поддерживаемых проектом.
Несколько вещей из моей головы:
Избегайте статических объектов в динамических библиотеках. Предоставьте надлежащие методы / функции инициализации для размещения объектов. Проблемы, возникающие во время загрузки библиотеки ОС (это когда вызываются c'tors для статических объектов), очень трудно отлаживать - помимо проблем с многопоточностью.
Заголовки интерфейса не могут содержать код. Никаких встроенных методов, никаких определений препроцессора. Это сделано для того, чтобы избежать заражения приложения кодом из конкретной версии библиотеки, что сделает невозможным замену библиотеки в более позднее время.
Заголовки интерфейса не могут содержать сами классы реализации - только абстрактные классы и фабричные функции . Аналогично предыдущему пункту - чтобы приложение не зависело от конкретной версии классов.Фабрики необходимы как способ для пользовательского приложения создать экземпляры конкретных классов реализации.
При представлении новой версии интерфейса, чтобы сохранить обратную совместимость, не изменяйте существующий абстрактный класс - создайте новый абстрактный класс, унаследованный от него, и добавьте туда новые методы. Смените фабрику, чтобы вернуть новую версию. (Вспомните MS 'IInterface, IInterface2, IInterface3 и т. Д.) В реализации используйте более новую версию абстрактного класса. Это за счет полиморфизма сделало бы реализацию обратно совместимой со старыми версиями интерфейса. (Это, очевидно, требует периодического обслуживания и очистки интерфейса - чтобы удалить старый мусор.)
Посмотрите на библиотеку boost.extension, она не является частью boost, но вы можете найти ее в песочнице. Он также немного заморожен, но в целом библиотека стабильна и проста в использовании.