Как код, написанный на одном языке, вызывается с другого языка - PullRequest
7 голосов
/ 08 мая 2009

Это вопрос, на который я всегда хотел знать ответ, но никогда не задавал.

Как код, написанный на одном языке, особенно на интерпретируемом языке, вызывается кодом, написанным скомпилированным языком.

Например, скажем, я пишу игру на C ++, и я передаю часть поведения AI, которое будет написано на Схеме. Как код, написанный на Scheme, достигает точки, пригодной для использования скомпилированным кодом C ++? Как он используется в исходном коде C ++ и как он используется в скомпилированном коде C ++? Есть ли разница в том, как он используется?

Относящиеся

Как несколько языков взаимодействуют в одном проекте?

Ответы [ 7 ]

13 голосов
/ 08 мая 2009

Нет единого ответа на вопрос, который работает везде. В общем, ответ заключается в том, что оба языка должны согласовать «что-то» - набор или правила или «протокол вызова».

На высоком уровне любой протокол должен указывать три вещи:

  • «Открытие»: как найти друг друга.
  • «связывание»: как установить соединение (после того, как они узнают друг о друге).
  • «Вызов»: как на самом деле делать запросы друг другу.

Подробности сильно зависят от самого протокола.

Иногда оба языка сговариваются, чтобы работать вместе. Иногда эти два языка соглашаются поддерживать некоторый внешний протокол. В наши дни ОС или «среда выполнения» (.NET и Java) также часто участвуют. Иногда способность распространяется только в одну сторону («A» может вызвать «B», но «B» не может вызвать «A»).

Обратите внимание, что это та же проблема, с которой сталкивается любой язык при взаимодействии с ОС. Знаете, ядро ​​Linux написано не на схеме!

Давайте посмотрим некоторые типичные ответы из мира Windows:

  • C с C ++ : C ++ использует искаженный («искаженный») вариант «протокола C». C ++ может вызывать C, а C может вызывать C ++ (хотя имена иногда бывают довольно грязными, и для перевода им может потребоваться внешняя помощь). Это не просто Windows; это в целом верно для всех платформ, которые поддерживают обе. В большинстве популярных ОС также используется «протокол C».

  • VB6 против большинства языков : предпочтительным методом VB6 является "протокол COM". Другие языки должны иметь возможность писать COM-объекты для использования из VB6. VB6 также может создавать COM-объекты (хотя и не все возможные варианты COM-объектов).

    VB6 также может говорить об очень ограниченном варианте «протокола C», а затем только делать вызовы снаружи: он не может создавать объекты, с которыми можно напрямую общаться через «протокол C».

  • .NET языки : все языки .NET взаимодействуют компилируются на один и тот же язык низкого уровня (IL). Среда выполнения управляет связью, и с этой точки зрения все они выглядят как один и тот же язык.

  • VBScript и другие языки : VBScript может использовать только часть протокола COM.

Еще одно замечание: SOAP «Веб-сервисы» на самом деле также являются «протоколом вызова», как и многие другие веб-протоколы, которые становятся популярными. В конце концов, речь идет о том, чтобы говорить с кодом, написанным на другом языке (и при этом работать в другом окне!)

4 голосов
/ 08 мая 2009

Существует протокол для взаимодействия модулей. Вот общий обзор того, как это работает:

  1. Создана библиотека для кода, которым вы хотите «поделиться». Это обычно называют DLL или SO в зависимости от вашей платформы.
  2. Каждая функция, которую вы хотите выставить (точка входа), будет доступна внешнему миру для привязки. Существуют протоколы для привязки, такие как соглашение о вызовах, которое определяет порядок передачи параметров, кто очищает стек, сколько параметров хранится в регистрах и какие и т. Д. См. Примеры cdecl, stdcall и т. Д. условные обозначения здесь .
  3. Затем вызывающий модуль будет статически или динамически связываться с разделяемой библиотекой.
  4. Когда ваша вызывающая библиотека привязана к общей библиотеке, она может указать, что она хочет привязаться к определенной точке входа. Обычно это делается по имени, однако большинство платформ также предлагают возможность привязки по индексу (быстрее, но еще более хрупко, если ваш модуль изменяется и точки входа переупорядочиваются).
  5. Вы также обычно объявляете функцию, которую хотите вызвать в своем модуле, чтобы ваш язык мог выполнять статическую проверку типов, знал, что такое соглашение о вызовах и т. Д.

Для вашего сценария вызова Scheme из C ++ интерпретатор Scheme, скорее всего, экспортирует функцию, которая динамически связывается с функцией / объектом Scheme и вызывает ее. Если модуль Scheme скомпилирован, он, вероятно, имеет возможность экспортировать точку входа, чтобы ваш модуль C ++ мог с ней связываться. Я не очень хорошо знаком со Схемой, так что кто-то другой, вероятно, сможет ответить на специфику этого конкретного связывания лучше, чем я.

4 голосов
/ 08 мая 2009

Обычно код C ++ вызывает интерпретатор для языка сценариев. Степень взаимодействия между скомпилированным и скриптовым кодом зависит от интерпретатора, но всегда есть способ передать данные между ними. В зависимости от интерпретатора может быть возможным манипулировать объектами на одной стороне с другой стороны, например, функцией C ++, вызывающей метод объекта Ruby. Может даже быть способ контролировать выполнение одного из другого.

2 голосов
/ 08 мая 2009

Вы также можете интегрировать две среды без необходимости компилировать библиотеку интерпретатора внутри вашего исполняемого файла. Вы сохраняете свой exe и exe Scheme как отдельные программы в вашей системе. Из вашего основного exe-файла вы можете записать свой код Scheme в файл, а затем использовать system () или exec () для запуска интерпретатора схемы. Затем вы анализируете вывод интерпретатора схемы.

Предложенный выше подход позволяет разделить exes отдельно, и вам не нужно беспокоиться о сторонних зависимостях, они могут быть значительными. Также проблемы остаются в том или ином exe.

Если запуск отдельного exe-файла не удовлетворяет вашим требованиям к производительности, вы можете разработать протокол, в котором интерпретатор Scheme становится сервером. Вам нужно написать некоторые функции Scheme, которые ожидают ввода в сокете или файле, оценивают этот ввод, а затем выводят результат в тот же сокет или другой файл. Другая итерация этого заключается в том, чтобы посмотреть на существующие серверы, на которых уже работает ваш интерпретатор, например, в apache есть модули, позволяющие писать код на многих языках.

1 голос
/ 09 мая 2009

Это было десятилетие или около того, но я сделал именно это для своего старшего замкового камня (ну, я построил обратно-распространяющуюся нейронную сеть в C и использовал программу схемы для обучения этому). Версия схемы, которую я использовал, имела как компилятор, так и интерпретатор, и я смог собрать его как файл .o. Я не знаю версию схемы, которую я использовал, но похоже, что RScheme превратит код вашей схемы в C.

1 голос
/ 09 мая 2009

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

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

Чтобы быть более конкретным в вашем вопросе, для интерпретируемых языков процесс довольно универсален, протокол обычно находится среди строк параметра командной строки, HTTP-запроса и других способов передачи простого текста. Возьмите первый пример, программа B получит вызов от HTTP-запроса в качестве ввода, а затем обработает запрос оттуда. Фактический формат ввода полностью определяется программой B.

Такие вещи, как SOAP и т. Д., - это просто способ упорядочить программы, чтобы они принимали участие в общепринятом стандарте.

1 голос
/ 08 мая 2009

Если вы действительно ищете инструменты для такой вещи, ответ адама см. swig .

...