Сделайте так, чтобы ваша DLL экспортировала функцию, возвращающую метаинформацию о самом плагине, то есть версии, зависимостях, экспортируемых функциях и т. Д. При просмотре каталога плагинов динамически загружайте библиотеки DLL в этом каталоге с помощью LoadLibrary
и проверяйте, экспортируют лисимвол, который соответствует вашей функции запроса (через GetProcAddress
).Если это так, загрузите библиотеку DLL, попробуйте запросить плагин и получить из него некоторую значимую информацию.
Обязательно используйте какой-либо вариант управления версиями для вашей системы плагинов, чтобы учесть изменения API.Сама Windows делает это путем передачи информации о версии (иногда в форме размеров структуры) определенным функциям.
Что касается зависимостей, создайте граф зависимостей.Если вы обнаружите круговую зависимость (например, используя алгоритм Флойда ), спросите пользователя, что делать, т.е. какой плагин отключить.Если в вашем графике нет циклов, вы можете пройти (направленный) график, чтобы определить порядок загрузки для плагинов.
Отредактируйте согласно вашему вопросу в комментарии:
Как DLL1 вызовет функцию, ожидаемую в DLL2?Я предполагаю, что инфраструктура плагинов должна была бы обеспечить что-то вроде GetPluginFuncAddr (plugin_ID, func_ID) [...]
Да, вы могли бы выставить подобную функцию или предоставить доступ к какому-либоглобально доступный реестр.Опять же, я бы посоветовал включить управление версиями, чтобы при необходимости плагины могли запрашивать определенную версию функции, которая, как известно, работает, позволяя обновлять, не нарушая существующие плагины.
как идентифицировать плагины и функции?Строки против GUID, или это тривиальная вещь, так как плагин должен просто предоставлять заголовки?
Смотрите, если вы разрабатываете плагин, используя функции / функции другого плагина, вы, вероятно, не хотитеВыполняйте загрузку плагина, проверку версии / совместимости и обработку ошибок каждый раз, когда вы пишете плагин, вместо этого вы, вероятно, ожидаете связать с заглушкой, которая делает шаблонные вещи для вас.Относительно того, как вы реализуете определение плагинов и функций, действительно зависит от вас.Конечно, GUID не является плохой идеей, когда речь идет об идентификации плагина (вместе с удобным для пользователя, понятным для человека именем и описанием), кроме этого, вы можете предложить список / дерево различных версий функций, например
UsefulPlugin@{1e2f253e-a3b2-4617-90f2-f323577ffddf}
|
\__ FunctionA
| |
| \_ v1.1
| |
| \_ v1.3
|
\__ FunctionB
|
\_ v1.0
... какие клиенты могут запрашивать необходимую информацию.Если вы хотите, вы можете даже предложить отражающую информацию, содержащую информацию о параметрах, возвращаемых значениях и т.п. вашей функции.