Как Вы связываете язык (Python, например) другому (скажите, C++)?

Возможно читать stdin путем создания дескриптора файла к php://stdin и затем читать из него с fgets() для строки, например (или, как Вы уже заявили, fgetc() для отдельного символа):

<?php
$f = fopen( 'php://stdin', 'r' );

while( $line = fgets( $f ) ) {
  echo $line;
}

fclose( $f );
?>
16
задан larryq 25 September 2009 в 05:55
поделиться

6 ответов

Интерпретаторы, написанные на C89 с отражением, кто знал?


У меня такое чувство, что вы ищете объяснение механизма, а не ссылку на API или инструкции о том, как его кодировать . Итак, насколько я понимаю. . .

Основной интерпретатор обычно написан на C и динамически связан. В динамически связанной среде даже C89 имеет определенное рефлексивное поведение. В частности, вызовы dlopen (3) и dlsym (3) загружают динамическую (обычно ELF) библиотеку и ищут адрес символа, названного строкой. Укажите этот адрес, и интерпретатор сможет вызвать функцию. Даже если он статически связан, интерпретатор может знать адрес функций C, имена которых в нем скомпилированы.

Итак, он ' Это просто вопрос, когда интерпретируемый код сообщает интерпретатору, что нужно вызвать конкретную встроенную функцию в конкретной собственной библиотеке.

Механизм может быть модульным. Библиотека расширений для интерпретатора, написанная в сценарии, может сама вызывать простые перехватчики для dlopen (3) и dlsym (3) и подключаться к новой библиотеке, которую интерпретатор никогда не знал о.

Для передачи простых объектов по значению несколько функций-прототипов обычно допускают различные вызовы. Но для объектов структурированных данных (представьте stat (2)) модуль-оболочка должен знать структуру данных. В какой-то момент, либо при упаковке модуля расширения, либо при его установке, модуль интерфейса C включает соответствующие файлы заголовков и вместе с рукописным кодом создает объект интерфейса. Вот почему вам может потребоваться установить что-то вроде libsqlite3-dev , даже если в вашей системе уже был sqlite3 ; только в пакете -dev есть файлы .h, необходимые для перекомпиляции кода связывания.

Я полагаю, мы могли бы резюмировать это, сказав: «это сделано грубой силой и незнанием» . : -)

12
ответ дан 30 November 2019 в 17:53
поделиться

Основная общая концепция известна как FFI , «Интерфейс внешних функций» - - для Java - это JNI, для Python - это «Python C API», для Perl - это XS и т. д. и т. д., но я так думаю » s синтаксис и семантика - часто для программистов, в основном использующих Python, самый простой способ написать модуль расширения Python, который компилируется до быстрого машинного кода и, возможно, использует некоторые существующие C-вызываемые библиотеки.

ctypes ] отличается от традиционных подходов FFI, хотя он сам описывается как «библиотека внешних функций для Python» - он полагается на внешний код, доступный в DLL (или эквивалентном, таком как .so динамической библиотеки в Linux), а также генерирует и выполняет код во время выполнения для доступа к такому динамически загруженному C-коду (обычно все делается с помощью явного программирования на Python - я не знаю оболочек ctypes, основанных на интроспекции и ctypes- генерация кода, пока). Удобно, чтобы избежать необходимости устанавливать что-либо специальное для простых задач доступа к существующим DLL с помощью Python, но я думаю, что он не масштабируется так же хорошо, как подходы, основанные на компоновщиках FFI (поскольку для этого требуется больше усилий во время выполнения и т. д., и т. д.). Я не знаю другой реализации такого подхода, ориентированного на другие языки, помимо ctypes для Python (я полагаю, что некоторые из них действительно существуют, учитывая сегодняшнюю распространенность пакетов DLL и .so, и было бы любопытно узнать о них)

7
ответ дан 30 November 2019 в 17:53
поделиться

Обычно в этих языках есть способ загрузки расширений, написанных на C. Интерфейс Java называется JNI (собственный интерфейс Java). Python имеет исчерпывающую документацию по интерфейсу расширения.

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

4
ответ дан 30 November 2019 в 17:53
поделиться

Есть два основных способа интеграции c / c ++ с python:

  • расширение: доступ к c / c ++ из python
  • встраивание: доступ к интерпретатору python из c / c ++

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

Подробное объяснение см. В этом учебном пособии .

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

Подробное объяснение см. В этом учебном пособии .

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

Подробное объяснение см. В этом учебном пособии .

2
ответ дан 30 November 2019 в 17:53
поделиться

Приведенные ниже концепции можно относительно легко обобщить, однако для ясности я буду часто ссылаться на C и Python.

Вызов C из Python

Это может работать, потому что большинство языков / архитектур / операционных систем нижнего уровня имеют четко определенные двоичные интерфейсы приложений, которые определяют все низкоуровневые детали того, как приложения взаимодействуют друг с другом и с операционной системой. В качестве примера приведем ABI для x86-64 (AMD64): Двоичный интерфейс приложения AMD64 System V . Он определяет все детали таких вещей, как соглашения о вызовах для функций и связывание с объектными файлами C.

С этой информацией разработчики языка должны

  1. реализовать ABI языка вы хотите позвонить в

  2. . Предоставьте интерфейс через язык / библиотека для доступа к реализация

(1) на самом деле почти бесплатна для большинства языков благодаря единственному факту, что их интерпретаторы / компиляторы написаны на C, который, очевидно, поддерживает C ABI :). По этой же причине сложно вызвать код C из реализаций языков, не закодированных на C, например, IronPython (реализация Python на C #) и PyPy (реализация Python в Python) не имеют особенно хорошей поддержки для вызова кода C, хотя я полагаю, что в IronPython была проделана некоторая работа по этому поводу.

Итак, чтобы сделать это конкретным, предположим, что у нас есть CPython (стандартная реализация Python, сделанная на C). Мы получаем (1) бесплатно, поскольку наш интерпретатор написан на C, и мы можем получить доступ к библиотекам C из нашего интерпретатора так же, как и из любой другой программы на C (dlopen, LoadLibrary и т. Д.). Теперь нам нужно предоставить возможность людям, пишущим на нашем языке, получить доступ к этим возможностям. Python делает это через API Python C / C ++ или ctypes . Всякий раз, когда программист пишет код, используя эти API, мы можем выполнить соответствующий код загрузки / вызова библиотеки для вызова библиотек.

Вызов Python из C

Это направление на самом деле немного проще объяснить. Продолжая предыдущий пример, наш интерпретатор CPython - это не что иное, как программа, написанная на C, поэтому он может экспортировать функции и компилироваться как библиотека / компилироваться с любой программой, которую мы хотим написать на C. CPython экспортирует набор C функции для доступа / запуска программы Python, и мы можем просто вызвать эти функции для запуска кода Python из нашего приложения. Например, одна из функций, экспортируемых библиотекой CPython: контекст, указанный в словари глобальные и местные с флаги компилятора, указанные в flags. Параметр start указывает начальный токен, который следует использовать для проанализировать исходный код.

Мы можем буквально выполнить код Python, передав этой функции строку, содержащую действительный код Python (и некоторые другие детали, необходимые для выполнения.) Подробнее см. Встраивание Python в другое приложение .

3
ответ дан 30 November 2019 в 17:53
поделиться

Для Perl есть два способа вызова подпрограмм C ++:

2
ответ дан 30 November 2019 в 17:53
поделиться
Другие вопросы по тегам:

Похожие вопросы: