Где я работаю, мы только что закончили выпуск функции, использующей dll, которая в значительной степени полагается на интерфейсы. DLL и все клиентские приложения написаны в Delphi. Нет необходимости в регистрации. Эта dll не является надлежащим com-сервером. Единственное ограничение состоит в том, что устройство, содержащее интерфейс, доступно как для dll, так и для клиентских приложений. Это позволило нам передавать сложные данные в и из приложений, использующих эту dll, без необходимости прибегать к указателям на записи, массивам или сигнатурам с чрезвычайно жирной функцией и без багажа, который будет вводить bpl или полностью совместимый COM-сервер.
Похоже, что она решила серьезную проблему, с которой у нас не было ни одной стороны. К сожалению, есть недостаток. Любое изменение интерфейса после его выпуска требует последующей перекомпиляции любых пользователей этого интерфейса. Это хорошо для проектов, которые являются частью одного и того же цикла выпуска, но некоторые из наших проектов имеют разные расписания выпуска.
Я исследовал это немного, и похоже, что обычной практикой является введение нового интерфейса, который наследуется от ранее выпущенного интерфейса, а не изменяет оригинальный интерфейс.
type
IOriginalInterface = interface
['{8B598EC1-AD92-4144-A1BE-9062C5EA0748}']
procedure DoSomething;
end;
INewInterface = interface(IOriginalInterface)
['{DD9D9DE0-0F87-4BC5-803C-74C8AB0F3E39}']
procedure DoSomethingElse;
end;
Это гарантирует, что старые исполняемые файлы, скомпилированные с использованием исходного интерфейса, продолжают работать.
Я заметил, что с открытыми инструментами RAD Studio api интерфейсы переименовываются всякий раз, когда вводится новый. Поэтому вместо того, чтобы давать новейшему интерфейсу новое имя, новый интерфейс получает исходное имя интерфейса, а оригинальный интерфейс переименовывается.
type
IOldInterface = interface
['{8B598EC1-AD92-4144-A1BE-9062C5EA0748}']
procedure DoSomething;
end;
IOriginalInterface = interface(IOldInterface)
['{DD9D9DE0-0F87-4BC5-803C-74C8AB0F3E39}']
procedure DoSomethingElse;
end;
Это, очевидно, хорошо работало для команды RAD Studio, а также сторонних поставщиков расширений. Это гарантирует, что любые клиенты, которые будут перекомпилированы, будут использовать последний интерфейс без каких-либо изменений кода. Я предполагаю, что это работает, потому что имя не имеет значения, и после компиляции кода все, что остается, - это определение интерфейса, которое разрешено с помощью GUID.
Сказав все это, это хорошее решение проблемы с версией интерфейса, с которой мы сталкиваемся сейчас? Есть ли какие-либо другие вопросы, о которых я должен знать?