Устройство Fore и его взаимодействие с COM

Филипп Пономарев

В предыдущей статье мы с вами познакомились с внутренним языком программирования в Prognoz Platform – Fore. Мы увидели его применимость и внутреннюю значимость для всего комплекса.

В этой статье предлагаю поговорить о более технических аспектах, таких как устройство Fore, механизмы связывания различных частей Prognoz Platform. Кроме этого, рассмотрим возможности работы Fore с Component Object Model, что позволяет нам взаимодействовать не только с объектами платформы, но и с внешними объектами.

О Prognoz Platform с точки зрения системного разработчика

Обратим свое внимание на внутреннее устройство Fore. Fore – внутренний язык программирования в Prognoz Platform, содержащий в себе несколько таких крупных частей, как лексический, синтаксический и семантический анализаторы – компилятор, генератор кода, а также интерпретатор полученных кодов. Архитектурно Prognoz Platform представляет собой набор взаимосвязанных COM-объектов, поэтому Fore в первую очередь ориентируется на работу с СОМ-объектами. Он поддерживает возможность импорта различных объектов из tlb-файлов, а также работу с COM-объектами напрямую. Примеры этих возможностей будут продемонстрированы дальше.

В предыдущей статье мы говорили о системных сборках. Любая системная сборка описана в метаданных на языке Fore, в таких сборках выполняется импорт из соответствующей этому системному модулю библиотеки, а также дополнительные системные и вспомогательные конструкции, упрощающие разработку. На этапе построения всего Prognoz Platform idl-файлы преобразуются в библиотеки типов – tlb-файлы. Дальше на основании программного кода в системных модулях происходит импорт из полученных tlb-файлов.

Скомпилированные модули, в свою очередь, встраиваются в Prognoz Platform.

Работа с COM-объектами

Прежде чем перейти к импорту из библиотек типов, рассмотрим работу с зарегистрированными COM-библиотеками напрямую. Для этого мы создадим простой проект, создадим внутри него файл на языке описания интерфейсов – idl, в котором будет простейший интерфейс, а также CoClass, описывающий этот интерфейс.

Для начала создадим ATLProject с помощью Visual Studio, оставив настройки по умолчанию. Добавим в решение ATL Simple Object. Зададим ему имя и ProgId, в дальнейшем Fore будет инстанцировать объект как раз по этому ProgId.

Для корректной работы на Fore с таким объектом необходимо указать, что это – Dual Interface.

Поместим следующий программный код в .idl-файл.

interface IComTester : IDispatch{ [id(1), propget] HRESULT Text([out, retval] BSTR* Value); [id(1), propput] HRESULT Text([in] BSTR Value); [id(2)] HRESULT Message(); };

Следующий программный код в .h-файл:

private: CComBSTR m_String; public: STDMETHOD(get_Text)(BSTR* Value); STDMETHOD(put_Text)(BSTR Value); STDMETHOD(Message)();

И программный код для .cpp-файла:

STDMETHODIMP CComTester::get_Text(BSTR* Value) { if (Value) { *Value = m_String.Copy(); return S_OK; } return E_POINTER; } STDMETHODIMP CComTester::put_Text(BSTR Value) { m_String = CComBSTR(Value); return S_OK; } STDMETHODIMP CComTester::Message() { CString tmpMesage(m_String); MessageBox(nullptr, tmpMesage, L"This is ComTester for Fore", MB_OK); return S_OK; }

Соберем нашу библиотеку и зарегистрируем ее с помощью command prompt и командой «regsvr32 Абсолютный_путь\TestOfComFromFore.dll».

Теперь нашу библиотеку можно найти в реестре в «HKEY_CLASSES_ROOT»:

Тем самым мы провели подготовительные действия: сейчас у нас в реестре есть ProgId для создания нашего CoClass’а, в котором есть свойство Text и метод Message, показывающий системный MessageBox. Продемонстрируем, как связать со всем этим Fore. Создадим Fore-форму, на нее положим EditBox и 3 Button:

Нам понадобятся события создания формы, а также события нажатия на кнопки. При создании формы инициализируем переменную типа Variant, которая будет содержать наш CoClass. Для этого необходимо написать следующий программный код:

inst:variant; Sub OBJ22859FormOnCreate(Sender: Object; Args: IEventArgs); Begin inst := variant.CreateObject("ComTesterForFore"); End Sub OBJ22859FormOnCreate;

При создании такого объекта как раз указывается наш ProgId.

Для задания свойства будем использовать следующий программный код:

Sub Button1OnClick(Sender: Object; Args: IMouseEventArgs); Begin inst.SetProperty("Text", EditBox1.Text); End Sub Button1OnClick;

Для получения свойства следующий программный код:

Sub Button2OnClick(Sender: Object; Args: IMouseEventArgs); Begin WinApplication.InformationBox("Current value is:" + (inst.GetProperty("Text") As string)); End Sub Button2OnClick;

И, наконец, для вызова метода:

Sub Button3OnClick(Sender: Object; Args: IMouseEventArgs); Begin inst.Invoke("Message"); End Sub Button3OnClick;

Убедимся, что все это работает, запускаем форму, нажимаем «put Text», после этого нажимаем «get Text» и видим:

Как мы могли обратить внимание, показался InformationBox, теперь нажмем на третью кнопку и увидим MessageBox уже из внешней библиотеки:

Работа напрямую с зарегистрированными библиотеками может быть очень полезной, например, при работе с Microsoft Office на Fore. Используя таким образом переменные типа Variant, можно писать программный код на подобии с VBA.

Теперь мы убедились, что Fore, хоть и является внутренним языком программирования, не ограничивается работой с Prognoz Platform в рамках нее самой и позволяет взаимодействовать с внешними объектами.

COM-import

Работа напрямую с объектами COM является очень мощным механизмом, который иногда бывает очень громоздким. Необходимо писать классы-обертки для работы с вариантами, выносить логику в отдельные функции или же использовать дублирование программного кода. Для облегчения работы с COM Fore имеет внутренние механизмы импортирования объектов из библиотек типов – tlb-файлов.

При разработке нашего проекта из предыдущего примера была построена библиотека типов «TestOfComFromFore.tlb», которая уже интегрируется в dll. Хотелось бы также акцентировать внимание на том, что по своей сути создание модуля с ComImport эквивалентно созданию своей системной сборки. Как было сказано раньше, системные сборки получаются из системных ppmodule, в которых выполняется ComImport, и это – одна из главных функций Fore: связывание всех компонентов Prognoz Platform в единое целое.

Давайте посмотрим, что можно сделать с помощью Fore, имея кроме dll и еще и tlb-файл. Обратим внимание на то, что dll должна быть зарегистрирована, чтобы была возможность создавать объекты по CLSID.

Создадим простую Fore-форму:

И сделаем простой программный код для нее:

Comimport From "TestOfComFromFore.tlb" Interface IComTester; Class ComTester:Object, IComTester End Class ComTester; End Comimport; Class OBJ1288Form: Form EditBox1: EditBox; Button1: Button; Sub Button1OnClick(Sender: Object; Args: IMouseEventArgs); Var c:ComTester; Begin c:= New ComTester.Create; c.Text:=editbox1.Text; c.Message; End Sub Button1OnClick; End Class OBJ1288Form;

Для того, чтобы импорт прошел корректно, мы предварительно положили наш tlb- файл в папку с Prognoz Platform, иначе нам пришлось бы указывать абсолютный путь.

Самое пристальное внимание необходимо обратить на начало этого программного кода: вначале мы видим ComImport. В нем мы из написанной нами ранее библиотеки импортировали интерфейс, а также CoClass, реализующий данный интерфейс. И это все, больше ничего описывать не надо. Не надо создавать различные объекты типа Variant, с этим классом уже можно работать, как с обычным Fore-классом, что наглядно видно в программном коде, обрабатывающем нажатие на кнопку. Fore поддерживает возможность импортирования интерфейсов, классов, перечислений.

Убедимся, что все работает:

Также стоит отметить, что при отсутствии tlb-файла, но при наличии dll, в которую он встроен, можно извлечь библиотеку типов:

Заключение

В данной статье мы посмотрели на Fore и Prognoz Platform с точки зрения системных программистов, а также на возможность работы Fore с Component Object Model.

Техническая среда не стоит на месте, в повседневной жизни все больше и больше внимания уделяется .NET, а у Prognoz Platform есть свой язык программирования, исполняемый в среде CLR – Fore.NET. В дальнейшем мы поговорим о Fore.NET, а именно, о том, как Fore взаимодействует с Fore.NET, и наоборот.

Читайте также

Комментарии

Подробнее о политике использования персональных данных