Подтвердить что ты не робот

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

Я далек от эксперта python, но я все время слышу это о своих связях с C/С++. Как работает эта концепция и как Python (и Java) связывается с API на основе C, например OpenGL? Этот материал всегда был для меня загадкой.

4b9b3361

Ответ 1

Переводчики, написанные на C89 с отражением, кто знал?


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

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

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

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

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

Полагаю, мы могли бы подвести итог, сказав: "Это было сделано с грубой силой и невежеством".: -)

Ответ 2

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

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

Существуют также специальные языки, такие как Cython, "расширенный поднабор" Python, предназначенный для легкого генерации кода FFI при совпадении большая часть синтаксиса и семантики Python - часто может быть самым простым способом для программистов на Python писать модуль расширения Python, который сводится к быстрому машинным кодам и, возможно, использует некоторые существующие C-вызываемые библиотеки.

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

Ответ 3

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

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

Ответ 4

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

Вызов C из Python

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

С помощью этой информации до разработчиков языка

  • Внедрение ABI языка вы хотите позвонить в

  • Обеспечьте интерфейс через языка/библиотеки для доступа к реализация

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

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

Вызов Python с C

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

PyObject* PyRun_StringFlags(const char *str, int start, PyObject *globals, PyObject *locals, PyCompilerFlags *flags)¶

Возвращаемое значение: Новая ссылка.

Выполнить исходный код Python из str в контекст, указанный словари, глобальные и локальные флагов компилятора, заданных флагами. Параметр start указывает начать токен, который должен использоваться для проанализируйте исходный код.

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

Ответ 5

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

Ответ 6

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

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

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

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