06.02.2023

Создание обертки C3D для использования на разных языках и платформах

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

Базовые требования обертки ядра от C3D Labs включают:

  • Поддерживаемость — любые изменения в ядре автоматически отражаются в обертке
  • Масштабирование — расширение обертки
  • Кроссплатформенность — по количеству компиляторов на разных операционных системах обертка должна удовлетворять тем же требованиям, что и ядро C3D.

Отметим, что первые две задачи должны выполняться быстро и зеркально.

Одна из задач в разработке современных программных продуктов (далее ПП, прим.) — снижение порога вхождения. Ее решением может быть, например, документация, снабженная большим количеством примеров, развитая техподдержка или возможность использования ПП на нескольких языках программирования. Такой подход облегчает возможности использования инженерных решений специалистами разных профилей.

Нужно отметить, что на данный момент уже существует обертка для языка C#, которая написана с использованием технологии C++/CLI. У этого решения существует ограничение: библиотеку нельзя использовать для иных систем кроме Windows. Также у неё достаточно сильно ограничена поддержка, т.к. исправления и доработки не автоматизированы. Именно поэтому подход в формировании оберток ядра подвергся изменениям.

Для унификации процесса нами принято решение создавать обертки в стиле языка Си. Такая обертка может применяться самостоятельно как в Си, так и в С++ приложениях. Также она является промежуточным звеном для формирования более высокоуровневых оберток, например, для языка C# с использованием технологии P/Invoke. Это, в свою очередь, позволяет производить сборку ядра как для Windows, так и для Linux систем.

Рассмотрим процесс создания обертки в стиле Си для библиотеки геометрического ядра C3D Labs. Он состоит из нескольких этапов:

  1. Создание обертки в стиле Си (прототип без автоматизации для тестирования жизнеспособности)
  2. Парсинг заголовочных файлов С++ на сущности языка
  3. Разработка правил формирования обертки
  4. Написание генератора Си обертки
  5. Формирование и сборка обертки ядра генератором

На первом (1) этапе по ограниченному набору файлов создается обертка в стиле СИ с целью проверки работоспособности и формирования ряда правил для будущего генератора обертки.

Создание обертки C3D для использования на разных языках и платформах, фото 1

На втором (2) этапе задействуется библиотека clang, которая разбирает заголовочный файл в представление AST (abstract syntax tree). Полученное представление clang сохраняется в структуры данных языка Python (для использования генератором обертки, написанным на Python).

На третьем (3) этапе формируется набор правил обработки структур данных С++.

Создание обертки C3D для использования на разных языках и платформах, фото 2

На четвертом этапе (4) используются результаты работы парсера и набор правил формирования.

Генератор работает следующим образом:

  • Получает на вход заголовочный файл C++
  • Запускает парсер по файлу и получает представление структур данных в сущностях языка Python
  • Формирует «заготовку» — файл со специальными функциями для создания/удаления объектов (классов, структур) библиотеки и функций доступа к родительским классам.
  • Проходя по сущностям из парсера, обрабатывает код согласно правилам и формирует соответствующие функции.

Результатом работы генератора является пара файлов (заголовочный и исполняемый коды) по входному заголовочному файлу.

Создание обертки C3D для использования на разных языках и платформах, фото 3
Рабочий цикл генератора

При формировании обертки встречаются некоторые ограничения:

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

На пятом (5) этапе выполняется формирование обертки генератором по набору заголовочных файлов. Далее весь результирующий набор файлов вместе с реализацией шаблонных классов собираются в один проект для построения библиотеки обертки. На этом этапе используются cmake-файлы для конфигурации сборки.

В результате мы получаем библиотеку обертки, которая может быть использована как основа для последующего уровня обертки (С#, Python) или как самостоятельный продукт. Также упрощается процесс сопровождения и модификации обертки, поскольку генерация по измененному коду ядра автоматически включает все изменения.

В наших дальнейших планах — автоматизация процесса генерации и сборки обертки в стиле Си (например, при выходе релиза основной библиотеки), формирование C# обертки на её основе, выпуск вышеуказанных оберток для Linux и Windows.

Максим Пылаев, инженер-программист C3D Labs
Автор:
Максим Пылаев
Инженер-программист C3D Labs

Поделиться материалом
Вверх