Upload
evgeny-shvarov
View
187
Download
0
Tags:
Embed Size (px)
DESCRIPTION
Caché Native Access - the way to call native binary libs from Caché Object Script in a very easy and robust way Способ работы с нативными библиотеками любых ОС из Caché Object Script наиболее простым и удобным способом, без создания специальных Callout библиотек.
Citation preview
Caché Native Access Новый механизм вызова сторонних библиотек
Дмитрий Трефилов Санкт-Петербург, 2014
История вопроса (RegEx)
• PCRE – Perl Compatible Regular Expressions • “The PCRE library is a set of functions that implement regular
expression pattern matching using the same syntax and semantics as Perl 5. PCRE has its own native API, as well as a set of wrapper functions that correspond to the POSIX regular expression API. The PCRE library is free, even for building proprietary software.”
• ~ 30 нужных экспортируемых функций • Задача не была завершена
это было давно и неправда…
История вопроса (ShellExecute)
• Shell32.DLL • lpOperation =
– edit • Launches an editor and opens the document for editing. If lpFile is not a document file, the
function will fail. – explore
• Explores a folder specified by lpFile. – find
• Initiates a search beginning in the directory specified by lpDirectory. – open
• Opens the item specified by the lpFile parameter. The item can be a file or folder. – print
• Prints the file specified by lpFile. If lpFile is not a document file, the function fails. – NULL
• The default verb is used, if available. If not, the "open" verb is used. If neither verb is available, the system uses the first verb listed in the registry.
ближе к истине
Что такое Callout…
• Встроенный механизм для вызова внешних библиотек (исполняемого кода) • Требует создания промежуточного модуля, созданного по определенным правилам
• Является посредником для вызова внешних функций – ~ 10000 экспортов функций в Windows 7 – ~ 50000 в Linux (RHEL 6)
• Статический подход – Компиляция ядра Caché
• Динамический подход – Загрузка библиотек и вызов функций «на лету»
• Недостатки – Требуются исходный код и настроенное окружение – Каждый раз необходима перекомпиляция и тестирование
…и с чем его едят
Что такое Callout… (часть 2) Существующая реализация («из коробки»)
void Function1(arg1) char * Function2() int FunctionN(a, b)
ZFENTRY Function1
ZFENTRY Function2
ZFENTRY FunctionN
Caché
Истина где-то рядом… ShellExecute + JNA (Java Native Access)
Классы Java libFFI
Диспетчер
Java Applet Библиотека : ИмяФункции (Аргументы…)
ИмяФункции (Аргументы…)
libFFI
• FFI stands for Foreign Function Interface. A foreign function interface is the popular name for the interface that allows code written in one language to call code written in another language. The libffi library really only provides the lowest, machine dependent layer of a fully featured foreign function interface. A layer must exist above libffi that handles type conversions for values passed between the two languages.
• The libffi library provides a portable, high level programming interface to various calling conventions. This allows a programmer to call any function specified by a call interface description at run-time.
https://sourceware.org/libffi/
libFFI (Part 2) Open Source and Ported to Many Different Platforms
ОС \ Arch Linux Windows Cygwin
Windows MingW iOS Mac OS X FreeBSD Solaris Tru64 AIX OpenBSD AMIGA OS/2 HURD IRIX
AArch64 (ARM64)
Alpha
ARM
AVR32
IA-‐64
MIPS
MIPS64
PowerPC
PowerPC 32-‐bit
PowerPC 64-‐bit
SPARC
SPARC64
TILE-‐Gx/TILEPro
X86
X86-‐64
Xtensa
Наш вариант совмещаем полезное с приятным
void Function1(arg1) char * Function2() int FunctionN(a, b)
Caché
libCNA libFFI Диспетчер
COS Callout Gateway
Библиотека : ИмяФункции (Аргументы…)
ИмяФункции (Аргументы…)
Применение
• Внешний движок регулярных выражений • Обработка изображений • Распознавание и конвертация данных • Компьютерное зрение • Научные вычисления • Работа с аудио/видео • Криптография • …
+100500 вариантов
Техническая реализация
Схема работы
Caché Native Access
Callout Gateway Caché libcna
libffi
external library
Класс CNA
Caché Native Access
• CNA — связка класса Caché и библиотеки, написанной на С
• CNA — интерфейс для вызова функций из любых динамических библиотек
• Ничего, кроме COS, для вызова функций не нужно
• Цель CNA — расширение функциональности Caché за счет существующих библиотек
Что это?
Caché Native Access
• $ZF(-1) , $ZF(-2)
• Позволяют вызывать системные команды и консольные программы
• Недостатки: – Сильно ограничена передача аргументов – Нет всей функциональности библиотек
Что есть сейчас? Caché Callout Gateway
Caché Native Access
• $ZF(-3) , $ZF(-5), $ZF( )
• Позволяют вызывать динамические и статические библиотеки специального вида (Callout Libraries)
• Недостатки: – Чтобы сделать из обычной библиотеки Callout Library необходимо:
• Иметь доступ к исходному коду • Иметь настроенное окружение для сборки • Для каждой функции прописать некоторое формальное описание
– Поддерживается очень ограниченный набор типов (int и указатели),
Что есть сейчас? Caché Callout Gateway
Caché Native Access
• Можно вызывать функции из любой динамической библиотеки, бинарно совместимой с C
• Поддержка всех простых типов языка C, size_t и указателей
• Поддержка структур (и вложенных структур)
• Поддержка потоков Caché
• Работает на Linux (x86-32/64), Windows (x86-32/64)
Возможности
Caché Native Access
• Linux:
– make libffi && make
• Windows
– make libffi && make в mingw или mingw-w64
– или можно загрузить бинарные файлы
• Импортируем файл cna.xml
– do $system.OBJ.Load("путь к cna.xml", "c")
Установка
Caché Native Access
CallFunction()
Класс CNA.CNA
LoadLibrary() FreeLibrary()
PointerGetAt() PointerSetAt()
ConvertStringToPointer() ConvertPointerToString() ConvertStreamToPointer()
NULL
#VOID #UCHAR #SCHAR #UINT #INT #USHORT #SHORT
#ULONG #LONG #UINT64 #INT64 #FLOAT #DOUBLE #LONGDOUBLE #POINTER #SIZET
Caché Native Access Пример работы с CNA
set cna = ##class(CNA.CNA).%New("libcna.dll") do cna.LoadLibrary("C:\Windows\system32\msvcrt.dll") set string = cna.ConvertStringToPointer("Hello") set argTypes = $lb(cna.#POINTER) set result = cna.CallFunction("strlen", cna.#SIZET, argTypes, string)
write result, ! do cna.FreeLibrary()
size_t strlen(const char *str);
Подробности реализации
Caché Native Access
• CNA основывается на libffi – libffi – интерфейс для вызова внешних функций – libffi поддерживает различные соглашения о вызове (calling
conventions)
• libffi – библиотека, написанная на C – То есть, для доступа в libffi из Caché, нужно использовать
Callout Gateway
• CNA – Callout Library и оболочка (wrapper) над libffi
Подробности реализации
Caché Native Access
• Мы хотим вызывать функцию, используя ее имя
• Однако, для использования libffi нужен адрес функции
• Чтобы получить адрес нужно использовать платформо-зависимые интерфейсы: POSIX и WinAPI
– Функции dlopen() и dlsym() из POSIX
– Функции LoadLibrary() и GetProcAddress() из WinAPI
Получение адреса функции
Caché Native Access
• Проблема: – Callout Gateway поддерживает очень мало типов данных
• Решение: – преобразовывать данные на стороне Caché – в CNA передавать строки с бинарными данными в формате языка C
Преобразование данных
А дальше что?
Ссылки на ресурсы
• Исходный код CNA и всех примеров выложен на github под лицензией MIT
– https://github.com/intersystems-‐ru/cna
• Документация по Caché Callout – http://docs.intersystems.com/cache20141/csp/docbook/
DocBook.UI.Page.cls?KEY=BGCL • libFFI
– https://sourceware.org/libffi/
полезные и не очень J
Планы
• %DispatchXXX и более удобная обвязка на стороне COS
• Пополнение примеров
• Расширение списка типов и платформ
• …
которых громадьё…
Используйте!
Делитесь успехами!
Спасибо за внимание! [email protected]
Caché Native Access Новый механизм вызова сторонних библиотек
Дмитрий Трефилов Санкт-Петербург, 2014