Преобразователь заголовочных файлов C++

Преобразователь заголовочных файлов C++ - это утилита, позволяющая создавать Ü биндинги для заголовочных файлов Си и C++. Заголовочные файлы Си поддерживаются полностью, но только ограниченное подмножество заголовочных файлов C++ может быть преобразовано. Данная утилита создана для упрощения взаимодействия Си кода с Ü. Выходной файл, создаваемый ею, может быть непосредственно импортирован в Ü коде, или же может быть сперва доработан вручную, если это необходимо.

Преобразователь заголовочных файлов C++ основан на исходном коде clang и поэтому может парсить любой корректный заголовочный файл Си, как это делают компиляторы Си. Так что не существует проблем с некорректным парсингом, что иногда случается с самописными парсерами Си.

Возможности и ограничения

Преобразователь заголовочных файлов C++ может создавать прототипы для функций, он может преобразовывать структуры, перечисления, псевдонимы типов и некоторые константные переменные. Но существуют некоторые ограничения, вытекающие из различий между языками Си и Ü:

  • Большинство функций должным образом переводятся с использованием модификатора nomangle и соглашением о вызове C.

  • Функции с именем, совпадающим с одним из ключевых слов Ü, игнорируются - они не могут быть использованы. Функции с именем, начинающимся с _, тоже игнорируются, т. к. идентификаторы в Ü не могут начинаться с _.

  • Функции с переменным числом аргументов не поддерживаются в Ü, Си функции с переменным числом аргументов становятся функциями с фиксированным числом аргументов в Ü.

  • Встроенные типы Си отображаются на соответствующие типы Ü (где это возможно).

  • Структуры преобразуются в Ü структуры с модификатором ordered.

  • Объединения и структуры с битовыми полями преобразуются как структуры с единственным полем - массивом элементов одного из byte-типов, так что размер и выравнивание этой структуры соответствуют размеру и выравниванию оригинала. Это делается, ибо в Ü нету ни объединений, ни битовых полей.

  • Неполные типы переводятся как пустые классы с отключённым конструктором по умолчанию, т. к. в Ü нету неполных типов.

  • Как const, так и не const указатели преобразуются в сырые указатели Ü, которые всегда считаются изменяемыми (не const).

  • Перечисления всегда переводятся как их нижележащие типы, члены перечислений становятся глобальными константами.

  • Безымянным структурам и перечислениям даются сгенерированные имена, ибо в Ü нету безымянных структур и перечислений.

  • Псевдонимы типов преобразуются в псевдонимы типов Ü, включая объявления псевдонимов типов, совмещённые с объявлением структур/перечислений.

  • Имена кроме имён функций могут быть переименованы, если имя не является корректным именем в Ü или же из-за конфликтов имён.

  • Вложенные структуры перемещаются в глобальное пространство имён (для простоты), при необходимости с переименованием для избежания конфликта имён.

  • Глобальные переменные преобразуются, но только если они объявлены как const и имеют вычислимый во время компиляции инициализатор. Глобальные переменные скалярных типов поддерживаются полностью. Массивы тоже поддерживаются, но только если количество элементов в их инициализаторе совпадает с размером массива. Структуры/объединения не поддерживаются.

  • Простые define, содержащие целочисленные, числовые или строковые литералы, переводятся как глобальные константы. Более сложные define игнорируются, включая даже define для отрицательных чисел.

Возможности и ограничения преобразования заголовочных файлов C++:

  • Поддерживаются только те функции, которые объявлены как extern "C" и имеют типы аргументов/возвращаемого значения, совместимые с Си.

  • Нешаблонные using-объявления переводятся должным образом как псевдонимы типов.

  • Классы преобразуются в структуры, метки видимости и функции-члены игнорируются.

  • Полиморфные классы/классы с наследованием не обрабатываются должным образом.

  • enum class переводятся как псевдоним для нижележащего типа. Для членов такого перечисления создаётся пространство имён с суффиксом _.

  • Пространства имён не поддерживаются, они скорее всего сломают данную утилиту.

  • Никакие шаблоны не поддерживаются, они скорее всего сломают данную утилиту.

Интерфейс командной строки

Базовый пример использования:

u.._cpp_header_converter some_c_header.h -o some_c_header_converted.uh -- -std=c11

Входные файлы указываются непосредственно.

Доступные опции командной строки:

-o - указать выходной файл.

--force-import - создать директиву импорта в выходном файле, импортирующую указанный файл.

--skip-declarations-from-includes - пропустить преобразование объявлений из включаемых файлов.

Кроме того могут быть указаны опции Си и C++ - после --. Т. к. преобразователь заголовочных файлов C++ основан на clang, поддерживается множество опций clang, см. соответствующую документацию. С преобразователем заголовочных файлов C++ наиболее часто используются опции стандарта (-std=c11, -std=c++17, и т. д.) и опция директории включений (-I).

Обычно преобразователь заголовочных файлов C++ поставляется вместе со внутренними заголовочными файлами clang, расположенными в директории вроде lib/clang/17/include в установочной директории Ü. Эта директория автоматически добавляется в список директорий для поиска включаемых файлов. Если это не так, путь к этой директории может быть указан явно через опцию -I.

Опции --force-import и --skip-declarations-from-includes могут быть использованы вместе, если надо преобразовать отдельно каждый заголовочный файл в иерархии включений и воссоздать её через import механизм в Ü.