OLE Automation, типы данных OLE и Dispatch-интерфейсы
1. OLE Automation
Автоматизация OLE — это способность управлять OLE другого приложения программным путем.
Приложения могут обеспечить доступ к своим сервисам через интерфейсы СОМ. После этого такими сервисами сможет воспользоваться любой фрагмент кода, способный вызывать методы СОМ-объекта. В СОМ такой стандартный способ обеспечения программируемости называется автоматизацией (Automation). Часто для создания программ, управляющих другими приложениями, используются простые языковые инструменты типа Visual Basic. Создаваемые ими программы называют также и сценариями (script).
Таким образом, цель программируемости — позволить приложению-серверу обеспечить доступ к своим сервисам со стороны внешних программ, чтобы сценарий мог делать все, что и обычный пользователь. Для этого можно воспользоваться интерфейсами СОМ. Однако, проблема в том, что рассмотренные нами ранее интерфейсы не совсем соответствуют возможности сред типа Visual Basic. Оказалось, что Visual Basic, являясь относительно простым языком, не совсем подходит для того, чтобы воспользоваться программируемостью. Есть проблемы при работе с указателями и маршалингом.
Для решения этой проблемы группа Visual Basic разработала стандартный СОМ интерфейс — IDispatch.
2. DISPATCH-интерфейсы
Объект, чей класс реализует интерфейс IDispatch, объявленный в модуле System Delphi, — есть объект Automation. Интерфейс типа IDispatch, определяет методы и свойства, которые объект Automation осуществляет через интерфейс IDispatch.
Как и любой обычный интерфейс, он реализован с помощью виртуальной таблицы указателей на методы. VMT интерфейса IDispatch начинается с трех хорошо известных методов IUnknown, за которыми следуют методы GetlDsOfNames, GetTypelnfo, GetTypelnfoCount и Invoke.
• Invoke (метод времени выполнения) — используется для вызова других методов Чтобы это было возможным, разработчик объекта, реализующего IDispatch должен определить, какие в точности методы будут доступны. Это достигается определением дополнительного диспетчерского интерфейса (dispatch interface), часто называемого диспинтерфейсом (dispinterface). Для его реализации VMT не используется. Каждому методу диспинтерфейса ставится в соответствие целое число — диспетчерский идентификатор (Dispatch IDentifier — DispID), no которому и производится вызов. Фактически реализация объектом метода Invoke является большим оператором Case.
• GetIDsOfNames — позволяет указывать в качестве параметра текстовое название интересующего метода. Если IDispatch находит на сервере метод с указанным названием, то возвращает его идентификатор DispID, который далее используется методом Invoke Фактически преобразует имя метода в его DispID.
• GetTypelnfo — возвращает указатель интерфейса ITypelnfo объекта — данные о типе, если у объекта есть библиотека типа. Следовательно, можно узнать все о вызове методов и упаковке параметров.
• GetTypelnfoCount — возвращает данные о том, будет ли вызов GetTypelnfo возвращать полезную информацию, т.е. есть ли у объекта библиотека типов (1\0 -Да\Нет).
3. Методика создания объектов автоматизации
Delphi позволяет создавать объекты автоматизации в составе внешних и внутренних серверов автоматизации.
а) Для создания внешнего сервера автоматизации следует:
• Создать новое приложение, которое будет играть роль сервера, выполнив команды:
File\New Application
После создания сохраним файл-unit под именем Unitl.pas, а файл-проект под именем OLEXE.DPR
• Для создания объекта автоматизации следует выполнить команды.
File\New
Automation Object. Будет запущен мастер по созданию объекта.
Первоначально в окне Automation Object Wizard необходимо указать Class Name (Sum), Instancing (Multiple Instance), Threading Model (Single).
Затем откроется окно библиотеки типов OLEXE.tlb, в котором необходимо указать все сведения о создаваемом Dispatch-интерфейсе. Сведения могут включать объявления методов и свойств.
Для объявления метода-функции необходимо объявить параметр, например Value, и определить ему возвращаемый тип (обязательно pointer — для этого достаточно указать * после нужного типа, например long*) и модификатор параметра [out, retval]. Так для метода GetSum мы должны указать: текст объявленных интерфейсов конструктор Delphi создаст сам. Автоматически будет создан и код Dispinterface.
OLE-объект определяется как CoClass, включающий обычно два метода (классовые функции): один для создания локального, другой — удаленного объекта:
CoSum=Class
Class Function Create(): ISum;
Class Function CreateRemote(Const MachineName: String): ISum; End;
После закрытия библиотеки типов и сохранения созданного файла-unit под именем Sum.pas, необходимо в этом файле реализовать методы объявленного интерфейса, например, следующим образом:
б) Для создания внутреннего сервера автоматизации следует:
• ActiveX Library.
• Для создания объекта автоматизации следует выполнить команды: File\New Automation Object
File\New
в) Экспонируемые методы и свойства, в принципе сервер автоматизации может содержать любые свойства и методы. Однако существует спецификация Microsoft на серверы автоматизации, которой следует руководствоваться при их создании. К свойствам, которые целесообразно указывать, относятся: FullName, Help, Left, Top и целый ряд других.
В реестре по GUID
В секции LocalServer32 будет указан путь до OLEXE.EXE.
В секции ProglD указано: «OLEXE.Sum»
В секции TypeLib указано: «{300587CF-5FE6-11D6-8EEA-00608C93D419}
В секции Version указано: «1.0»