Понять интерфейс внешних функций (FFI) и привязку языка

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

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

Мои вопросы:

  • Каковы различия между 1, 2 и 3 пути? Кажется мне все они должны составить код названный язык в некоторые библиотека с объектными файлами и заголовком файлы, которые затем вызываются вызывающий язык.
  • Один источник, который он связывает, говорит: реализация FFI может быть выполнена в несколько способов:

    • Требование, чтобы вызываемые функции на целевом языке конкретный протокол.
    • Реализация библиотеки-обертки, которая берет данный низкоуровневый язык функции и "обертывает" его кодом для преобразования данных в/из высокоуровневые языковые соглашения.
    • Требование функций, объявленных native, использовать подмножество высокоуровневой функциональности (совместимой с языком низкого уровня).

    Мне было интересно, если первый способ связанный источник тот же, что и первый путь в Википедии?

    Что делает третий способ в этом источник означает? Соответствует ли это 4-му пути в Википедии?

  • В тот же источник, при сравнении трех способов, которые он перечисляет, кажется, говорит задача заполнения разрыва между два языка постепенно смещено от названного языка на язык вызова. я был интересно, как это понимать? Это смещение также верно для четырех способов в Википедии?
  • Являются привязка к языку и FFI эквивалентные понятия? Как они связанные и отличаются?

    привязка с языка программирования к библиотеке или службе ОС - это API предоставляя эту услугу в язык.

  • Мне было интересно, какой путь в цитате из Википедии или из источника принадлежит каждому из следующих примеров?

Спасибо за ваше просвещение! С наилучшими пожеланиями!

Ответы

Ответ 1

Может быть, конкретный пример поможет. Возьмем язык хоста как Python и гостевой язык как C. Это означает, что Python будет вызывать функции C.

  • Первый вариант - написать библиотеку C определенным образом. В случае Python стандартным способом было бы иметь функцию C, написанную с первым параметром Py_Object * среди других условий. Например (отсюда):

    static PyObject *
    spam_system(PyObject *self, PyObject *args)
    {
        const char *command;
        int sts;
    
        if (!PyArg_ParseTuple(args, "s", &command))
            return NULL;
        sts = system(command);
        return Py_BuildValue("i", sts);
    }
    

    - функция C, вызываемая из Python. Для этого библиотека должна быть написана с учетом совместимости с Python.

  • Если вы хотите использовать уже существующую библиотеку C, вам нужен другой вариант. Один из них - иметь инструмент, который генерирует обертывание этой существующей библиотеки в формате, подходящем для потребления на языке хоста. Возьмите Swig, который можно использовать для привязки многих языков. Учитывая существующую библиотеку C, вы можете использовать swig для эффективного генерации кода C, который вызывает вашу существующую библиотеку, в то время как она соответствует соглашениям Python. См. пример для создания модуля Python.

  • Другим вариантом для нас уже существующей библиотеки C является вызов ее из библиотеки Python, которая эффективно переносит вызовы во время выполнения, например ctypes. Хотя в варианте 2 была необходима компиляция, на этот раз это не так.

Другое дело, что существует много вариантов (которые перекрывают) для вызова функций на одном языке с другого языка. Есть FFI (эквивалент языковых привязок, насколько я знаю), которые обычно относятся к вызову между несколькими языками в одном и том же процессе (как часть одного и того же исполняемого файла, так сказать), и есть средства межпроцессного взаимодействия (локальные и сетевые), Такие вещи, как CORBA и веб-службы (SOAP или REST), а также COM + и удаленные вызовы процедур в целом относятся ко второй категории и не рассматриваются как FFI. Фактически, они в основном не предписывают какой-либо конкретный язык, который будет использоваться по обе стороны сообщения. Я бы слегка использовал их как параметры IPC (interprocess communication), хотя это упрощение в случае сетевых APi, таких как CORBA и SOAP.

Пройдя в ваш список, я бы рискнул сделать следующее:

  • Архитектура брокер Common Object Request: IPC, а не FFI
  • Вызов C в С++, с помощью объявления extern "C" в С++, чтобы отключить управление именами. ****
  • Вызов C в Matlab по интерфейсу MATLAB для общих библиотек Вариант 3 (ctypes-like)
  • Вызов C в Matlab, создание файлов C/С++ MEX-Files Вариант 2 (swig-like)
  • Вызов Matlab в C с помощью mcc-компилятора Вариант 2 (swig-like)
  • Вызов С++ в Java, JNI и вызов Java в С++ с помощью JNI Вариант 3 (ctypes-like)
  • Вызов C/С++ на других языках, использование SWIG Вариант 2 (swig)
  • Вызов C в Python, с помощью Ctypes Вариант 3 (ctypes)
  • Cython Вариант 2 (swig-like)
  • Вызов R в Python, RPy Вариант 3 (ctypes-like) частично и частично об обмене данными (не FFI)

Следующие два не являются внешними интерфейсами функций, поскольку этот термин используется. FFi - это взаимодействие между языками программирования и должно быть способно сделать любую библиотеку (с соответствующими ограничениями) с одного языка, доступного другому. Отдельная библиотека, доступная с одного языка, не делает FFI.

  • Язык программирования Привязки к OpenGL с разных языков
  • Привязки для библиотеки C с разных языков