Интерфейс внешней функции

редактировать
Интерфейс для вызова функций из других языков программирования

A Интерфейс внешней функции (FFI ) представляет собой механизм, с помощью которого программа, написанная на одном языке программирования , может вызывать подпрограммы или использовать службы, написанные на другом языке.

Содержание
  • 1 Именование
  • 2 Операция
  • 3 По языку
  • 4 Особые случаи
  • 5 См. Также
  • 6 Ссылки
  • 7 Внешние ссылки
Именование

Термин взят из спецификации для Common Lisp, которая явно относится к языковым возможностям для межъязыковых вызовов как таковых; этот термин также официально используется в языках программирования Haskell и Python. В других языках используется другая терминология: язык программирования Ada говорит о «языковых привязках », а Java ссылается на свой FFI как на JNI (Java Native Интерфейс ) или JNA (Java Native Access ). Интерфейс внешних функций стал общей терминологией для механизмов, которые предоставляют такие услуги.

Операция

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

  • Требовать, чтобы функции гостевого языка, которые должны быть вызываемыми на языке хоста, были указаны или реализованы определенным образом; часто используют какую-либо библиотеку совместимости.
  • Использование инструмента для автоматического «оборачивания» функций на гостевом языке с помощью соответствующего связующего кода, который выполняет любой необходимый перевод.
  • Использование библиотек-оболочек
  • Ограничение набора возможностей основного языка, которые могут использоваться в разных языках. Например, функции C ++, вызываемые из C, могут (как правило) не включать ссылочные параметры или вызывать исключения.

FFI могут быть осложнены следующими соображениями:

  • Если один язык поддерживает сборку мусора (GC), а другой нет; Следует позаботиться о том, чтобы код языка, отличного от GC, не сделал ничего, чтобы вызвать сбой GC в другом. В JNI, например, код C, который «удерживает» ссылки на объекты, которые он получает от Java, должен «зарегистрировать» этот факт в среде выполнения Java (JRE); в противном случае Java может удалить объекты до того, как C завершит работу с ними. (Код C также должен явно освободить свою ссылку на любой такой объект, если C больше не нуждается в этом объекте.)
  • Сложные или нетривиальные объекты или типы данных могут быть трудными для отображения из одной среды в другую.
  • Может оказаться невозможным для обоих языков поддерживать ссылки на один и тот же экземпляр изменяемого объекта из-за проблемы сопоставления, описанной выше.
  • Один или оба языка могут работать на виртуальная машина (ВМ); более того, если и то, и другое, вероятно, это будут разные виртуальные машины.
  • Межъязыковое наследование и другие различия, такие как между системами типов или между объектами -компонентные модели могут быть особенно сложными.
По языку

Примеры FFI включают:

  • языковые привязки Ada, позволяющие не только вызывать сторонние функции, но и экспортировать их функции и методы, которые должны вызываться из кода, отличного от Ada.
  • C ++ имеет тривиальный FFI с C, так как языки имеют значительное общее подмножество. Основным эффектом объявления extern «C» в C ++ является отключение изменения имени C ++ .
  • Clean обеспечивает двунаправленный FFI для всех языков, следующих за C или соглашение о вызовах stdcall.
  • CNI, альтернатива JNI, используемая в среде компилятора GNU.
  • D делает это так же, как C ++, с extern "C" через extern (C ++)
  • Dart включает библиотеку dart: ffi для вызова собственного кода C для мобильных, командной строки и серверных приложений
  • Динамический языки, такие как Python, Perl, Tcl и Ruby, все обеспечивают легкий доступ к собственному коду, написанному на C / C ++ (или любой другой язык, подчиняющийся соглашениям о вызовах C / C ++).
  • Factor имеет FFI для C, Fortran, Objective-C и Windows COM ; все они позволяют динамически импортировать и вызывать произвольные разделяемые библиотеки.
  • В FFI Common Lisp и Haskell
  • Fortran 2003 есть модуль ISO_C_BINDING, который предоставляет интероперабельные данные типы (как внутренние типы, так и структуры POD), совместимые указатели, совместимые глобальные хранилища данных и механизмы для вызова C из Fortran и для вызова Fortran из C.
  • Go может вызывать код C напрямую через "C"псевдопакет.
  • GWT, в котором Java скомпилирован в JavaScript, имеет FFI, называемый JSNI, который позволяет исходному тексту Java вызывать произвольные функции JavaScript, а для JavaScript - вызывать обратно в Java.
  • JNI, который обеспечивает интерфейс между Java и C / C ++, предпочтительными системными языками в большинстве систем, где развернута Java. JNA предоставляет интерфейс с собственными библиотеками без необходимости писать связующий код. Другой пример: JNR
  • Julia имеет ключевое слово ccallдля вызова C (и других языков, например Fortran); в то время как пакеты, обеспечивающие аналогичную поддержку без шаблонов, доступны для некоторых языков, например для Python (например, для обеспечения поддержки OO и GC), Java (и поддерживает другие языки JDK, такие как Scala) и R. Интерактивное использование с C ++ также возможно с пакетом Cxx.jl.
  • PHP предоставляет От FFI до C.
  • Python предоставляет модули ctypes и cffi. Например, модуль ctypes может загружать функции C из разделяемых библиотек / DLL на лету и автоматически переводить простые типы данных между семантикой Python и C следующим образом:
    import ctypes libc = ctypes.CDLL ('/ lib / libc.so.6') # В Linux / Unix t = libc.time (None) # Эквивалентный код C: t = time (NULL) print (t)
  • P / Invoke, который обеспечивает интерфейс между Microsoft Common Language Runtime и собственным кодом.
  • Racket имеет собственный FFI, в значительной степени основанный на макросах, который позволяет импортировать произвольные общие библиотеки динамически.
  • Raku может вызывать Ruby, Python, Perl, Brainfuck, Lua, C, C ++, Go и схема Guile / Gambit
  • Rust также определяет интерфейс внешней функции.
  • Visual Basic имеет декларативный синтаксис, позволяющий вызывать не -Функции Юникода C.
  • Одной из основ модели компонентных объектов является общий формат интерфейса, который изначально использует те же типы, что и Visu al Basic для строк и массивов.
  • LuaJIT, своевременная реализация Lua, имеет FFI, который позволяет «вызывать внешние функции C и использовать C структуры данных из чистого кода Lua ».
  • PhoneGap (назывался Apache Callback, но теперь Apache Cordova) - это платформа для создания собственных мобильных приложений с использованием HTML, CSS и JavaScript. Кроме того, есть FFI через функции обратного вызова JavaScript для доступа к методам и свойствам встроенных функций мобильного телефона, включая акселерометр, камеру (также PhotoLibrary и SavedPhotoAlbum), компас, хранилище (база данных SQL и локальное хранилище), уведомление, мультимедиа и захват (воспроизведение и запись или аудио). и видео), файл, контакты (адресная книга), события, устройства и информация о подключении. [1], [2].
  • Wolfram Language предоставляет технологию под названием WSTP (Wolfram Symbolic Transfer Protocol), который обеспечивает двунаправленный вызов кода между другими языками с привязками для C ++, Java,.NET и других языков.

Кроме того, многие FFI могут быть сгенерированы автоматически: например, SWIG. Однако в случае языка расширения может произойти семантическая инверсия отношений гостя и хоста, когда меньшая часть языка расширения - это гость, вызывающая службы в большей части основного языка, например написание небольшого плагина для GIMP.

Некоторые FFI ограничены автономными функциями, в то время как другие также позволяют вызывать функции, встроенные в объект или класс (часто называемые вызовами методов ); некоторые даже позволяют переносить сложные типы данных и / или объекты через языковые границы.

В большинстве случаев FFI определяется языком «более высокого уровня», поэтому он может использовать службы, определенные и реализованные на языке более низкого уровня, обычно системном языке, таком как C или C ++. Обычно это делается либо для доступа к службам ОС на языке, на котором определен API ОС, либо из соображений производительности.

Многие FFI также предоставляют вызываемому языку средства для вызова служб на основном языке.

Термин "интерфейс внешней функции" обычно не используется для описания многоязычной среды выполнения, такой как Microsoft Common Language Runtime, где предоставляется общий "субстрат", позволяющий использовать любой CLR-совместимый язык. использовать сервисы, определенные в любом другом. (Однако в этом случае CLR действительно включает FFI, P / Invoke, для вызова вне среды выполнения.) Кроме того, многие архитектуры распределенных вычислений, такие как вызов удаленного метода Java (RMI), RPC, CORBA, SOAP и D-Bus позволяют писать разные службы на разных языках; такие архитектуры обычно не считаются FFI.

Особые случаи

Существуют некоторые особые случаи, когда языки компилируются в одну виртуальную машину с байт-кодом, например, Clojure и Java, а также как Эликсир и Эрланг. Поскольку интерфейса нет, это не FFI, строго говоря, хотя он предлагает те же функции для пользователя.

См. Также
Ссылки
Внешние ссылки
Последняя правка сделана 2021-05-20 11:14:31
Содержание доступно по лицензии CC BY-SA 3.0 (если не указано иное).
Обратная связь: support@alphapedia.ru
Соглашение
О проекте