Язык программирования Перфолента.Net - Официальный сайт

 Язык программирования Перфолента.Net - Официальный сайт.

Поиск   
Главная :: О проекте :: Контакты :: Обратная связь :: Благодарности :: ВходГость

   >   >   >   > 



Интеграция языков программирования Перфолента.Net и OneScript

Самое приятное для программиста, когда необходимый код уже есть и ничего писать не надо. Но что делать, если этот код написан на другом языке программирования? В этой статье Вы найдете ответы на вопрос, как использовать код Перфоленты в программах на OneScript и наоборот.


От любви до ненависти несколько тысяч строк кода.

«Используй то, что под рукою, и не ищи себе другое.»

Филеас Фогг.

Когда Вы пишете программу на Перфоленте, Вы можете обнаружить, что кто-то уже написал то, что Вам нужно, на другом языке программирования. Хорошо бы просто взять и использовать имеющуюся библиотеку или код. Язык программирования Перфолента.Net позволяет использовать библиотеки или код написанные на многих языках. Существует и обратная задача, код, написанный на Перфоленте, тоже можно использовать в программах написанных на других языках.

Кроме использования уже написанного кода, могут быть и другие причины, чтобы использовать код написанный на другом языке. Например, если какая-то часть Вашей программы работает слишком медленно или не может обратиться напрямую к «железу», Вы можете написать её на более низкоуровневом языке. Если Вы хотите дать пользователям возможность на лету изменять логику работы Вашей программы, то Вы можете прикрутить к ней возможность выполнять скрипты на более высокоуровневом языке или языке предметной области пользователя.

Эта статья начинает цикл статей про интеграцию языка Перфолента.Net с другими языками.

И начнем мы с OneScript.

Цитата с официального сайта: «OneScript позволяет создавать и выполнять текстовые сценарии, написанные на языке, знакомом любому специалисту по системе 1С:Предприятие. Применение знакомого языка для скриптовой автоматизации позволяет значительно повысить продуктивность специалиста за счет более простой автоматизации ручных операций». Автор языка OneScript - Андрей Овсянкин, однако, сегодня в развитии языка и библиотек участвуют множество людей. Проект OneScript можно найти на GitHub.

Рассмотрим, как использовать код написанный на языке Перфолента.Net в программах на языке OneScript и наоборот.

Различия в языках.

Синтаксически, оба языка являются надмножествами языка . Язык Перфолента включает, но очень сильно расширяет базовый синтаксис языка , а OneScript почти соответствует языку , хотя в последнее время понемногу выходит за его рамки.

Как у Перфоленты, так и у OneScript существуют свои особенности. Перфолента компилируемый язык, а OneScript интерпретируемый. Перфолента язык со статической типизацией (хотя, возможна и динамическая), а OneScript с динамической. Перфолента полностью интегрирована с .Net, а OneScript слабо. Код Перфоленты выполняется очень быстро, примерно на том же уровне, что и код на языке C#, а код OneScript выполняется значительно медленней (хотя, недавно анонсирован OneScript.Native, в котором обещают предоставить возможность компиляции в машинный код, что значительно повысит производительность).

В целом, Перфоленту выгодно использовать из OneScript для увеличения производительности и взаимодействия с .Net, с операционной системой или с библиотеками, написанными на Си-подобных языках, например, c Windows API. А OneScript из Перфоленты выгодно использовать, как язык знакомый пользователям .
Готовый код, написанный на любом из этих языков, в том числе библиотеки, выгодно использовать в любом направлении.

 

 

Вызываем OneScript из Перфоленты.

Существует несколько способов запустить код OneScript из Перфоленты.

 

Из командной строки.

Если код надо просто выполнить, то можно воспользоваться встроенными функциями КомандаСистемы или ЗапуститьПриложение:

Функцию КомандаСистемы используйте в том случае, если скрипт должен выполниться скрытно, без открытия окна консоли, а функцию ЗапуститьПриложение используйте, если скрипт должен показать окно консоли пользователю.

//окно консоли не будет открыто
КомандаСистемы("oscript ВыполнитьНастройку.os");

//окно консоли будет открыто
ЗапуститьПриложение("oscript Змейка.os");

В этих примерах предполагается, что путь к интерпретатору oscript.exe находится в переменной окружения Path, а скрипты ВыполнитьНастройку.os и Змейка.os находятся в текущей папке. Если это не так, просто укажите полные пути к интерпретатору и запускаемому скрипту.

Вы также можете указать в строке запуска любые ключи, которые поддерживает интерпретатор OneScript или передать параметры скрипту.

 

Запускаем как процесс.

Если необходимо контролировать запущенную программу, то лучше всего создать для неё отдельный процесс.

Класс Процесс находится в стандартной библиотеке Перфоленты, поэтому в программе должна присутствовать директива #ИспользоватьСтандартнуюБиблиотеку.

Проц = Новый Процесс("oscript");
Проц.АргументыКоманднойСтроки = "Змейка.os";
Проц.ЗапускатьЧерезОболочкуОС = Истина;
Проц.Старт();
// Ждем, когда процесс завершит работу
Проц.ОжидатьЗавершения();

В этом случае мы просто ожидаем завершения скрипта, но при необходимости можно осуществлять более тонкий контроль или даже общаться с процессом скрипта, если скрипт может это делать.

 

Используем метод Пуск класса Консоль.

Если программа на Перфоленте является консольным приложением, а скрипт, написанный на OneScript, должен вывести в эту же консоль свои результаты, то можно запустить скрипт методом Пуск класса Консоль.

Класс Консоль находится в стандартной библиотеке Перфоленты, поэтому в программе должна присутствовать директива #ИспользоватьСтандартнуюБиблиотеку.

//этот метод перехватит вывод скрипта и отобразит его в своей консоли
Консоль.Пуск("oscript", "ПоказатьНастройку.os")

Внимание!!! В этом случае, скрипт выполняется в отдельном процессе без пользовательского интерфейса!!! Поэтому не получится использовать методы работы с консолью, которые изменяют её характеристики, такие как цвет текста, цвет фона, позиция курсора, ширина и высота буфера и так далее. Вы должны использовать в скрипте только ввод и вывод.

 

Используем класс ИсполнительКода.

Если необходимо запустить на выполнение код OneScript, полученный из любого источника в виде строки, то для запуска можно использовать класс ИсполнительКода.

Класс ИсполнительКода находится в стандартной библиотеке Перфоленты, поэтому в программе должна присутствовать директива #ИспользоватьСтандартнуюБиблиотеку.

Класс ИсполнительКода может работать в двух режимах, которые определяются значением свойства ПерехватыватьИсключения. Если отключить перехват исключений и воспользоваться оператором Попытка, то кода будет меньше, однако, проверка ошибок после каждого действия с исполнителем кода может дать большую гибкость.  Рассмотрим примеры для обоих режимов:

ТекстСкрипта="Сообщить(""Скрипт работает!!!"");"

//в этом примере будем проверять ошибку после каждой команды исполнителя
ИспКода = Новый ИсполнительКода(ЯзыкиПрограммирования.ОСкрипт, ТекстСкрипта
Если ИспКода.ЕстьОшибка
    ВыводСтроки "Ошибка компиляции: "+ИспКода.ИнформацияОбОшибке.Описание
Иначе
    //текст откомпилировался, можем его выполнить
    ИспКода.Выполнить 
    Если ИспКода.ЕстьОшибка
        ВыводСтроки "Ошибка выполнения:"+ИспКода.ИнформацияОбОшибке.Описание
    КонецЕсли
КонецЕсли

//в этом примере отключим режим перехвата ошибок и воспользуемся оператором Попытка
Попытка
    ИспКода = Новый ИсполнительКода(ЯзыкиПрограммирования.ОСкрипт)
    ИспКода.ПерехватыватьИсключения = Ложь
    ИспКода.ИсходныйКод = ТекстСкрипта
    ИспКода.ПараметрыКоманднойСтроки = "-парам1 -парам2"
    ИспКода.Выполнить
Исключение Ош
    ВыводСтроки Ош.ОписаниеОшибки
КонецПопытки

Обратите внимание, ИсполнительКода запускает код OneScript в том же процессе в котором выполняется программа Перфоленты, т.е. скрипт и программа выполняются как одно целое. Ввод и вывод программы на языке OneScript перенаправляются в консоль программы на Перфоленте.

Класс ИсполнительКода поддерживает исполнение кода на нескольких языках программирования, а не только на OneScript. Вы можете запустить код на C#, VB.Net и некоторых других языках, если ИсполнительКода сможет найти их интерпретаторы или компиляторы в операционной системе.

 

Интегрируем OneScript в программу на Перфоленте.

Если загрузить библиотеки OneScript в программу, то можно будет запускать любой код OneScript налету и даже запускать отдельные методы в любом порядке.

Рассмотрим пример:

#ЗагрузитьСборку "ScriptEngine.dll"
#ЗагрузитьСборку "ScriptEngine.HostedScript.dll"

ИмпортИмен ScriptEngine.Environment
ИмпортИмен ScriptEngine.Machine
ИмпортИмен ScriptEngine.Machine.Contexts
ИмпортИмен ScriptEngine.HostedScript

Программа ПодключениеОСкрипт

    Процедура Старт
    
        ТекстСкрипта="
        |Перем Поле;
        |
        |Функция МетодФункцияБезПараметров() Экспорт
        |    Возврат ""Работает МетодФункцияБезПараметров! Поле=""+Поле;
        |КонецФункции
        |
        |Функция МетодФункцияСПараметром(А) Экспорт
        |    Возврат ""Работает МетодФункцияСПараметром! Параметр=""+А;
        |КонецФункции
        |
        |Процедура МетодПроцедура() Экспорт
        |    Поле=""Новое значение поля"";
        |КонецПроцедуры
        |
        |Поле=""Начальное значение поля"";"

        СкриптМашина = Новый HostedScriptEngine();
        СкриптМашина.Initialize();
        СкриптМашина.AttachAssembly(System.Reflection.Assembly.GetExecutingAssembly());
        Скрипт = СкриптМашина.EngineInstance.AttachedScriptsFactory.LoadFromString(
                    СкриптМашина.EngineInstance.GetCompilerService(), ТекстСкрипта);

        Попытка
        
            //выполняем процедуру
            НомерМетода = Скрипт.FindMethod("МетодПроцедура");
            Перем Результат тип IValue = Неопределено;
            Массив Аргументы[] тип IValue;
            Скрипт.CallAsProcedure(НомерМетода, Аргументы);

            //выполняем функцию без параметров
            НомерМетода = Скрипт.FindMethod("МетодФункцияБезПараметров");
            Скрипт.CallAsFunction(НомерМетода, Аргументы, Результат);
            ВыводСтроки "Результат = "+Результат.AsString;
            
            //выполняем функцию с параметром
            НомерМетода = Скрипт.FindMethod("МетодФункцияСПараметром");
            МассивИзменить Аргументы[0]; 
            Аргументы[0] = ValueFactory.Create("Аргумент функции"); 
            Скрипт.CallAsFunction(НомерМетода, Аргументы, Результат);
            ВыводСтроки "Результат = "+Результат.AsString;
            
        Исключение Ош
            ВыводСтроки "Ошибка: "+Ош.ОписаниеОшибки;
        КонецПопытки
        
        ВводСтроки
        
    КонецПроцедуры
КонецПрограммы

Обратите внимание, что в каталоге программы должны присутствовать библиотеки ScriptEngine.dll, ScriptEngine.HostedScript.dll и OneScript.Language.dll, которые можно взять из каталога /bin, находящегося в каталоге, в который установлен OneScript. Эти же библиотеки вы должны будете включить в поставку вашей программы.

Как видно из примера, этот способ позволяет не только выполнить тело скрипта, но и запускать отдельные его методы в любой последовательности и в любой момент.

 

 

Вызываем Перфоленту из OneScript.

Существует несколько способов запустить код Перфоленты из OneScript.

 

Из командной строки.

Программа на Перфоленте может существовать в двух видах, которые можно запустить из командной строки:

·         В откомпилированном виде, как приложение с расширением *.exe, которое может запуститься самостоятельно;

·         В виде скрипта, как текстовый файл программы с расширениями *.pfls или *.пфлс, который надо запускать с помощью компилятора pflc.exe;

Если код надо просто выполнить, то можно воспользоваться встроенной функцией ЗапуститьПриложение:

//окно консоли будет открыто
ЗапуститьПриложение("МояПрограмма.exe");
ЗапуститьПриложение("pflc.exe ВыполнитьНастройку.пфлс");

В этих примерах предполагается, что путь к компилятору pflc.exe находится в переменной окружения Path или он находится в текущей папке, а скрипт ВыполнитьНастройку.пфлс и программа МояПрограмма.exe находятся в текущей папке. Если это не так, просто укажите полные пути к компилятору Перфоленты и к запускаемому скрипту.

Вы также можете указать в строке запуска любые ключи, которые поддерживает интерпретатор OneScript или передать параметры скрипту.

 

 

Запускаем как процесс.

Если необходимо контролировать запущенную программу, то лучше всего создать для неё отдельный процесс:

//вспомогательная процедура
Процедура Вывести(Поток)
    Текст = Поток.Прочитать();
    Если ЗначениеЗаполнено(Текст) Тогда
        Сообщить(Текст);
    КонецЕсли;
КонецПроцедуры

//создадим процесс и запустим его
Процесс = СоздатьПроцесс("pflc ВыполнитьНастройку.пфлс", ,Истина);
Процесс.Запустить();
//ожидаем завершения процесса
Пока Не Процесс.Завершен Цикл
    Вывести(Процесс.ПотокВывода);
    Вывести(Процесс.ПотокОшибок);
КонецЦикла;
Вывести(Процесс.ПотокВывода);
Вывести(Процесс.ПотокОшибок);
//проверим код возврата процесса
Если Процесс.КодВозврата <> 0 Тогда
    ВызватьИсключение "Процесс завершился с ошибкой";
КонецЕсли;

 

 

Подключаем библиотеку Перфоленты как внешнюю компоненту.

В языке OneScript существует возможность подключить библиотеку dll, написанную на одном из .Net языков, как внешнюю компоненту, и затем использовать экспортируемые ею классы, создавая экземпляры объектов во время выполнения.

Несмотря на то, что эта возможность не обеспечивает полной интеграции с любыми библиотеками dll, всё же её можно использовать для написания на Перфоленте простых библиотек для OneScript.

Напишем и откомпилируем библиотеку dll на языке Перфолента:

#ТипСборки Библиотека
//***************************
&ВидноВсем
Класс Котик
    &ВидноВсем Свойство Имя тип Строка = ""Безымянный""
    &ВидноВсем
    Функция Мяу() тип Строка
       Возврат "МЯУ!!!"
    КонецФункции
КонецКласса

В результате у нас получился файл Котик.dll, который мы и подключим в качестве внешней компоненты:

ПодключитьВнешнююКомпоненту("Котик.dll");
Котик = Новый COMОбъект("Котик");
Сообщить("Было имя: "+Котик.Имя);
Котик.Имя="Васька";
Сообщить("Стало имя: "+Котик.Имя);
Сообщить("Котик сказал "+Котик.Мяу());

В классе Котик, можно создать любой набор необходимых конструкторов, методов и свойств. При создании библиотеки для OneScript на языке Перфолента, в качестве типов данных, которые передаются в параметры методов или присваиваются свойствам, желательно использовать совместимые типы Булево, Дата, Число, Строка и Объект.

 

 

Используем библиотеку perfolenta.

В предыдущих способах код программы на Перфоленте хранился на диске компьютера в виде файла. Однако, существует способ, позволяющий на лету компилировать и запускать код, интегрированный прямо в текст программы OneScript.

Существует специальная библиотека perfolenta для OneScript, которая позволяет упростить запуск кода, написанного на языке Перфолента. Код Перфоленты при использовании этой библиотеки выполняется в том же процессе, что и текущий скрипт OneScript.

Скачать библиотеку можно из репозитория GitHub «PerfolentaForOneScript». Там же описано, как её установить и использовать.

Рассмотрим три варианта использования библиотеки.

Первый вариант: Компилируем и выполняем код одним методом.

Методы КомпилироватьИВыполнить и КомпилироватьИВыполнитьИзФайла подходят для однократного или редкого выполнения кода Перфоленты, т.к. компиляция происходит при каждом вызове метода, что занимает некоторое время.

Метод Старт модуля Программа может быть функцией или процедурой, но обязательно с одним параметром, имеющим тип совместимый с типами языка OneScript. Для функции возвращаемое значение так же должно иметь тип совместимый с типами языка OneScript.

Если необходимо передать в метод Старт несколько параметров, то Вы можете поместить их в массив или в другую перечисляемую коллекцию и передать её через параметр типа Объект.

#Использовать perfolenta
Скрипт = "
|Программа ЗапускКода
|    Функция Старт(Чис тип Число) тип Строка
|       ВыводСтроки Чис*Чис
|       Возврат ""Программа Перфоленты выполнена!""
|    КонецФункции
|КонецПрограммы";
//создадим объект предоставляющий доступ к компилятору языка Перфолента
П = Новый Перфолента;
Сообщить("Результат = "+П.КомпилироватьИВыполнить(Скрипт, 999));

Второй вариант: Сначала компилируем, а затем многократно выполняем код.

В начале вызывается один из методов Компилировать или КомпилироватьИзФайла, а затем вызов метода Выполнить повторяется необходимое количество раз.

Метод Старт модуля Программа может быть функцией или процедурой, помеченной атрибутом &ВидноВсем или &ВидноСборке, но обязательно с одним параметром, имеющим тип совместимый с типами языка OneScript. Для функции возвращаемое значение так же должно иметь тип совместимый с типами языка OneScript.

Если необходимо передать в метод Старт несколько параметров, то Вы можете поместить их в массив или в другую перечисляемую коллекцию и передать её через параметр типа Объект.

П = Новый Перфолента;
П.Текст = "
|Программа ЗапускКода
|    &ВидноСборке Функция Старт(Чис тип Число) тип Строка
|       ВыводСтроки Чис
|       Возврат ""ОК! Выполнено!!!""
|    КонецФункции
|КонецПрограммы
|";
//указываем имя модуля Программа, если оно задано в скрипте...
П.Компилировать("ЗапускКода");
//команду Выполнить можно запускать многократно с разными параметрами
Результат = П.Выполнить(333);
Результат = П.Выполнить(555);
Результат = П.Выполнить(777);

Третий вариант: Сначала компилируем библиотеку классов, а затем создаём экземпляры объектов и используем их свойства и методы.

Для того, чтобы использовать в коде OneScript классы, определенные в программе на Перфоленте, необходимо подключить откомпилированную сборку как внешнюю компоненту.

П = Новый Перфолента;
П.Текст = "
|&ВидноВсем Класс Котик    
|    &ВидноВсем Свойство Имя тип Строка = ""Безымянный""
|    //---------------------------
|    &ВидноВсем Функция Мяу() тип Строка
|       Возврат ""МЯУ!!!""
|    КонецФункции
|    
|КонецКласса    
|";
П.Компилировать(); 
П.ПодключитьКакВнешнююКомпоненту();
Котик = Новый COMОбъект("Котик");
Сообщить("Было имя: "+Котик.Имя);
Котик.Имя="Васька";
Сообщить("Стало имя: "+Котик.Имя);
Сообщить(Котик.Мяу());

Обратите внимание, что каждая компиляция создаёт в домене приложения новую сборку, поэтому выбирайте такую архитектуру кода, чтобы количество компиляций было минимальным. Хотя, сборки небольших программ занимают в памяти всего несколько десятков килобайт, при работе 24/7 приложение может занимать всё больше и больше оперативной памяти компьютера, если компиляция кода повторяется снова и снова.

 

 

Редактируем код OneScript в редакторе Перфоленты.

Основным редактором OneScript является редактор «Visual Studio Code» и именно его рекомендуется использовать в повседневной работе. Однако, при интеграции с Перфолентой и в некоторых других случаях, вполне удобно редактировать и запускать код OneScript из редактора Перфоленты.

Редактор Перфоленты поддерживает раскраску кода OneScript, имеет набор полезных шаблонов, простое авто дополнение кода, подсказки и ссылки на официальные ресурсы. 

 

 

Вывод: Можно использовать разными способами код, написанный на языке программирования Перфолента.Net, в программах на языке OneScript, и точно также, можно использовать разными способами код, написанный на языке программирования OneScript, в программах на языке Перфолента.Net.

 




К началу статьи


Предыдущая статья:
Бром. Универсальный SOAP сервис обмена данными между 1С и Перфолента.Net

Вернуться в раздел:
Практика программирования на языке Перфолента
  Поддержи проект!

Вы можете поддержать разработку Перфоленты, перечислив любую удобную сумму, которая пойдет на развитие языка и поддержку инфраструктуры сайта.

  Новости:
      04.01.2025 Опубликован новый релиз дистрибутива языка программирования Перфолента.Net версии 0.4.15.0_CE
      23.09.2024 Опубликована новая статья: "Конструируем класс. Делегаты."
      30.08.2024 Опубликован новый релиз дистрибутива языка программирования Перфолента.Net версии 0.4.14.0
      24.05.2024 Обновлён справочный раздел сайта
      01.07.2023 Новая версия 0.4.13.0 языка программирования Перфолента.Net
       Все новости