Создаем "кроссплатформенную" библиотеку для OneScript и 1С:Предприятие

Программирование - Практика программирования

48
Описана методика создания внешних компонент для OneScript и 1С:Предприятие, переносимых на уровне прикладного кода.

Введение

Не так давно, для создания одного web-приложения на OneScript, мне понадобились компоненты для преобразования текста из формата markdown в html, а также чтения файлов в формате yaml. После изучения руководства, необходимые компоненты были созданы и я мог использовать их в своем web-приложении. Однако, в связи с отсутствием отладки в http-сервисах OneScript, разработка web-приложения велась в конфигураторе 1С:Предприятие, благо переносимость обеспечивается на уровне Ctrl+C, Ctrl+V. В связи с этим встал вопрос о том, как обеспечить функционал созданных  библиотек  в среде 1С:Предприятие, а также обеспечить переносимость кода. Ниже описана методика, позволяющая решить озвученные проблемы . Она не претендует на новизну и является работоспособной компиляцией хорошо известных приемов.

 

Выбор технологии

Платформа 1С:Предприятия представляет два способа, для подключения сторонних библиотек – это технология внешних компонент (NativeAPI), а также технология COM. Ввиду сложности использования технологии NativeAPI, для реализации функционала внешних компонент в среде 1С:Предприятие была выбрана технология COM. Несмотря на то, что она не является кросплатформенной, создание внешних компонент на основе этой технологии несложно и достаточно подробно описано в различных источниках, например:

https://www.codeproject.com/Articles/7859/Building-COM-Objects-in-C

https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/interop/example-com-class

//1c.digi-mas.ru/public/140411/

Поскольку внешние компоненты OneScript используют типы, определенные в ядре движка, их непосредственное использование для создания COM компоненты затруднительно и наиболее быстрым подходом, является копирование функционала внешней компоненты путем создания промежуточных классов или Ctrl+C, Ctrl+V.

 

Пример реализации

В качестве примера реализации вышеизложенного подхода, используем компоненту преобразования текста, в формате markdown в текст, в формате html. Исходный код, а также бинарные файлы расположены по нижеследующим ссылкам:

https://github.com/jdeshin/OneScript-Markdig

https://github.com/jdeshin/OneScript-Markdig/releases

Данная внешняя компонента OneScript реализует нижеследующие функции (в скобках указаны англоязычные наименования функций):

СконфигурироватьРасширения (ConfigureExtensions)

ПолучитьHtmlИзMarkdown(GetHtmlFromMarkdown)

ПолучитьСтрокуИзMarkdown(GetStringFromMarkdown)

В данном случае, мы создадим COM visible сборку, с функциями, имена которых совпадают с англоязычными наименованиями в компоненте OneScript и скопируем туда функционал исходных функций (в данном случае я использовал Ctrl+C, Ctrl+V).

После компиляции, мы получаем dll, которую можно зарегистрировать как COM объект при помощи regasm и использовать в 1С:Предприятие.

Ниже приведены примеры использования компоненты из среды OneScript и 1С:Предприятие.

 

1С:Предприятие

 

ТекстMarkdown = "This is a text with some *emphasis*";


// Создание COM-объекта является платформо-зависимым

Процессор = Новый COMОбъект("MarkdigMarkdownProcessorCom.MarkdigMarkdownProcessor");

Процессор.ConfigureExtensions("yaml+advanced");

ТекстHtml = Процессор.GetHtmlFromMarkdown(ТекстMarkdown);

 

 

OneScript

 

ТекстMarkdown = "This is a text with some *emphasis*";


Процессор = Новый MarkdownПроцессорMarkdig;

Процессор.ConfigureExtensions("yaml+advanced");

ТекстHtml = Процессор.GetHtmlFromMarkdown(ТекстMarkdown);

 

 

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

 

Более сложный случай

К сожалению, не всегда есть возможность одинаковой реализации интерфейса в компоненте OneScript и COM объекте. В качестве примера такой библиотеки, рассмотрим компоненту, которая преобразует текст в формате yaml в дерево соответствий и массивов. Исходный код, а также бинарные файлы расположены по нижеследующим ссылкам:

https://github.com/jdeshin/OneScript-YamlDotNet

https://github.com/jdeshin/OneScript-YamlDotNet/releases

Данная компонента имеет единственную функцию:

ПрочитатьYaml (ReadYaml)

И все бы ничего, однако функция возвращает не примитивный тип, а в общем случае дерево, состоящее из соответствий, массивов и примитивных типов. Соответственно в 1С:Предприятие эти коллекции будут выглядеть как COM объекты, а доступ к ним будет возможен при условии, что возвращаемые объекты являются COM visible и то, как показывает практика не всегда. На основании всего вышеизложенного возможны два варианта – это написание COM оберток к возвращаемым типам, с реализацией необходимого функционала или реализация функций доступа к элементам коллекций. Выберем второй вариант, как более простой.

Для реализации функционала библиотеки в среде 1С:Предприятие, создадим COM объект, реализующий необходимые функции:

 

ReadYamlString – осуществляет преобразование и возвращает дерево объектов как COM объект

GetValueType – возвращает тип объекта. 0 – Соответствие (Dictionary), 1 – Массив (ArrayList), 2 – Простое значение

GetByIndex – возвращает объект из массива по индексу.

GetByKey – возвращает объект из коллекции типа Соответствие по ключу.

ToArray – преобразует коллекцию соответствие в массив Структур Ключ, Значение

GetKeyByIndex – получает значение ключа по индексу из массива пар Ключ, Значение

GetValueByIndex – получает Объект по индексу из массива пар Ключ, Значение

 

После компиляции, мы получаем dll, которую можно зарегистрировать как COM объект при помощи regasm и использовать в 1С:Предприятие.

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

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

 

 

// Модуль, реализующий прикладной интерфейс для работы с компонентой чтения Yaml
// Необходим для переносимости кода, между OneScript и 1С:Предприятие

// Создает новый объект процессора Yaml
//
Функция НовыйYamlПроцессор() Экспорт
	
	// Закомментировать в OneScript
	Возврат Новый COMОбъект("YamlDotNetProcessorCom.YamlDotNetYamlProcessor");
	// Раскомментировать в OneScript
	//Возврат Новый YamlПроцессорYamlDotNet;
	
КонецФункции


// Функция, эмулирующая одноименную функцию в OneScript
//
Функция ПрочитатьYaml(СтрокаYaml, Процессор = Неопределено) Экспорт

	Если Процессор = Неопределено Тогда
		Процессор = НовыйYamlПроцессор();
	КонецЕсли;
	
	// Раскомментировать в OneScript
	// Возврат Процессор.ПрочитатьYaml(СтрокаYaml);
	// Закомментировать в OneScript
	Объекты = Процессор.ReadYamlString(СтрокаYaml);
	Возврат ПолучитьЗначение(Объекты, Процессор);
	
КонецФункции

// Получает значение объекта в зависимости от типа возвращенного COM-объекта
// Необходимо закомментирвать в OneScript
//
Функция ПолучитьЗначение(Объект, Процессор)
	
	ТипОбъекта = Процессор.GetValueType(Объект);
	Результат = Неопределено;
	
	Если ТипОбъекта = 2 Тогда
		
		// Это простое значение, возвращаем его
		Результат = Объект;
		
	ИначеЕсли ТипОбъекта = 0 Тогда
		
		// Это соответствие
		Результат = Новый Соответствие;
		МассивОбъектов = Процессор.ToArray(Объект);
		Количество = МассивОбъектов.Count;
		
		Для Индекс = 0 По Количество - 1 Цикл
			
			Ключ = Процессор.GetKeyByIndex(МассивОбъектов, Индекс);
			Значение = ПолучитьЗначение(Процессор.GetValueByIndex(МассивОбъектов, Индекс), Процессор);
			Результат.Вставить(Ключ, Значение);
			
		КонецЦикла;
		
	ИначеЕсли ТипОбъекта = 1 Тогда
		
		// Это массив
		Результат = Новый Массив;
		Количество = Объект.Count;
		
		Для Индекс = 0 По Количество - 1 Цикл
			
			Значение = ПолучитьЗначение(Процессор.GetByIndex(Объект, Индекс), Процессор);
			Результат.Добавить(Значение);
			
		КонецЦикла;
		
	КонецЕсли;
	
	Возврат Результат;
	
КонецФункции  

Теперь, разместив данный модуль в конфигурации и общих модулях web-приложения OneScript, мы получим прикладной код, который можно переносить между платформами OneScript и 1С:Предприятие простым копированием. В случае вышеописанной библиотеки, прикладной код в OneScript и 1С:Предприятие будет выглядеть примерно следующим образом:

Процессор = YamlПроцессор.НовыйYamlПроцессор();
Объекты = YamlПроцессор.ПрочитатьYaml(СтрокаYaml, Процессор);

Update:

Реализована работа с библиотекой MarkdigMarkdownProcessor как с обработкой для использования совместно с каркасной конфигурацией версии 2.0. Подсистема для сравнения/объединения - БиблиотекаMarkdownПроцессор.

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

Функция ОбработкаВызоваHTTPСервиса(Запрос) Экспорт
	
	Макет = ПолучитьОбщийМакет("ДемоТекстMarkdown");
	ПроцессорMarkdown = Обработки.MarkdownПроцессор.Создать();
	Результат = ПроцессорMarkdown.ПолучитьHtmlИзMarkdown(Макет.ПолучитьТекст());
	
	Ответ = Новый HTTPСервисОтвет(200);
	Ответ.УстановитьТелоИзСтроки(Результат);
	
	Возврат Ответ;
	
КонецФункции

Реализована работа с библиотекой YamlDotNet как с обработкой для использования совместно с каркасной конфигурацией версии 2.0. Подсистема для сравнения/объединения - БиблиотекаYamlПроцессор.

Теперь, работа с библиотекой в OneScript и 1С:Предприятие выглядит примерно следующим образом:

Функция ОбработкаВызоваHTTPСервиса(Запрос) Экспорт
	
	Макет = ПолучитьОбщийМакет("ДемоYamlПроцессор");
	ПроцессорYaml = Обработки.YamlПроцессор.Создать();
	Результаты = ПроцессорYaml.ПрочитатьYaml(Макет.ПолучитьТекст());
	
	Ответ = Новый HTTPСервисОтвет(200);
	Ответ.УстановитьТелоИзСтроки(Результаты.Получить("ИмяБиблиотеки") + ": " + Результаты.Получить("Описание"));
	
	Возврат Ответ;
	
КонецФункции

Заключение

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

48

Скачать файлы

Наименование Файл Версия Размер
Библиотека работы с yaml для каркасной конфигурации 2.0:
.cf 9,56Mb
13.06.18
0
.cf 9,56Mb Скачать
Библиотека работы с markdown для каркасной конфигурации 2.0:
.cf 9,65Mb
13.06.18
1
.cf 9,65Mb 1 Скачать

См. также

Комментарии
Сортировка: Древо
1. nomadon 287 07.02.18 14:44 Сейчас в теме
вроде написано кроссплатформенно а на маке не запускается(
2. blackhole321 759 07.02.18 14:49 Сейчас в теме
Кросплатформенная между платформами 1С и OneScript.
Поддерживаемые ОС: Для 1С:Предприятие - Windows, для OneScript - Windows, Linux (Ubuntu)
3. sttt 113 11.02.18 14:37 Сейчас в теме
(2) 1с и на linux прекрасно работает
4. blackhole321 759 11.02.18 15:15 Сейчас в теме
(3)Да, но COM-объекты только под Windows
5. sttt 113 11.02.18 15:48 Сейчас в теме
Это да, но есть натив... что-то там))
Не внимательно прочитал, извиняюсь
7. blackhole321 759 11.02.18 16:52 Сейчас в теме
(5)ну оно конечно можно сделать и через NativeAPI, только это сложнее, и учитывая количество установок на Windows и Linux, на мой взгляд оно того не стоит
6. sttt 113 11.02.18 15:51 Сейчас в теме
Я вроде где-то читал, что 1с скрипт и с нативными библиотеками работали, что сбило с толку
Оставьте свое сообщение