Может ли двоичный код C ++ стать переносимым через собственный интерфейс C? Каковы ограничения?

Я часто использую эту технику, чтобы обернуть мои высокопроизводительные классы C ++ тонким слоем C, который я компилирую в разделяемые библиотеки, а затем загружаю их в другие языки программирования, такие как Python.

Из моего чтения здесь и там я понимаю, что единственное требование, чтобы это работало, это наличие интерфейсов функций использовать только нативные типы или структуры этих типов. (так, int а также longs, float, doubleи т. д. и их указатели любого ранга).

Мой вопрос: при условии полного Совместимость с ABI между различными компиляторами, это единственное требование, которое я должен выполнить, чтобы иметь полную совместимость API с общей библиотекой?

Почему библиотеки C ++ нельзя портировать? Вот мое понимание:

Случай 1: Рассмотрим тип std::string, Внутренне он содержит char* строка с нулевым символом в конце и целое число размера. Стандарт C ++ не говорит, какой из них должен стоять первым (верно?). Это значит, что если я поставлю std::string на интерфейсе функций два разных компилятора могут иметь их в разном порядке, что не будет работать.

Случай 2: Рассмотрим наследование и vtables для класса с виртуальными методами. Стандарт C ++ не требует какой-либо конкретной позиции / порядка для того, куда должны идти указатели vtable (верно?). Они могут находиться в начале класса перед любой другой переменной, а также в конце после всех других переменных-членов. Итак, еще раз, взаимодействие этого класса с функцией не будет согласованным.

Дополнительный вопрос после моего первого: Разве эта проблема не возникает и внутри вызовов функций? Или это ничего не значит после того, как он скомпилирован в двоичный файл, а типы больше не имеют значения? Не вызовут ли элементы RTTI проблемы, например, если я помещу их в интерфейс оболочки C?

1

Решение

Причина, почему нет C ++ ABI, отчасти потому, что нет C ABI. Как заявил Бьярн Страуструп (источник):

Наиболее сложной технической проблемой, вероятно, является отсутствие двоичного интерфейса C ++ (ABI). Также нет C ABI, но на большинстве (всех?) Платформ Unix есть доминирующий компилятор, и другие компиляторы должны были соответствовать его соглашениям о вызовах и правилам компоновки структуры — или стали неиспользованными. В C ++ есть и другие вещи, которые могут меняться — например, расположение таблицы виртуальных функций — и ни один из поставщиков не создал C ++ ABI с помощью fiat, исключив всех конкурентов, которые не соответствовали требованиям. Точно так же, как раньше было невозможно связать код из двух разных компиляторов PC C, как правило, невозможно связать код из двух разных компиляторов Unix C ++ вместе (если нет переключателей совместимости).

Отсутствие ABI дает больше свободы для реализации компилятора и позволяет распространять языки на несколько различных типов систем.

В Windows есть некоторые зависимости для конкретной платформы, которые зависят от того, как компилятор выводит результат. COM где чисто виртуальные интерфейсы должны быть выложены определенным образом. Так что в Windows большинство компиляторов, по крайней мере, согласятся с этим.

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

4

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector