Spec-Zone.ru › Python 3.14

Сборка расширений C и C++ в Windows

В этой главе кратко объясняется, как создать модуль расширения для Python в Windows с помощью Microsoft Visual C++, а затем приводится более подробная справочная информация о принципах его работы. Эти пояснения будут полезны как программистам Windows, которые учатся создавать расширения для Python, так и программистам Unix, заинтересованным в разработке программного обеспечения, которое можно успешно собирать и в Unix, и в Windows.

Авторам модулей рекомендуется использовать подход distutils для сборки модулей расширения вместо описанного в этом разделе. Вам по-прежнему понадобится компилятор C, с помощью которого был собран Python; обычно это Microsoft Visual C++.

Примечание

В этой главе упоминается несколько имён файлов, содержащих закодированный номер версии Python. В этих именах файлов номер версии обозначен как XY; на практике 'X' будет номером основной версии, а 'Y' — номером дополнительной версии выпуска Python, с которым вы работаете. Например, если вы используете Python 2.2.1, XY будет иметь вид 22.

5.1. Практический подход

Для сборки модулей расширения в Windows, как и в Unix, есть два подхода: использовать пакет setuptools для управления процессом сборки или выполнять всё вручную. Подход setuptools хорошо подходит для большинства расширений; документация по использованию setuptools для сборки и упаковки модулей расширения доступна в разделе Сборка расширений C и C++ с помощью setuptools. Если вы действительно решили всё делать вручную, полезно будет изучить файл проекта стандартного библиотечного модуля winsound.

5.2. Различия между Unix и Windows

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

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

В Windows файл динамически подключаемой библиотеки (.dll) не содержит неразрешённых ссылок. Вместо этого доступ к функциям и данным осуществляется через таблицу поиска. Поэтому при выполнении коду DLL не нужно корректироваться для обращения к памяти программы: он уже использует таблицу поиска DLL, а во время выполнения таблица поиска изменяется так, чтобы указывать на функции и данные.

В Unix существует только один тип файла библиотеки (.a), содержащий код из нескольких объектных файлов (.o). При компоновке для создания файла общего объекта (.so) компоновщик может обнаружить, что ему неизвестно, где определён идентификатор. Компоновщик будет искать его в объектных файлах библиотек; если он его найдёт, то включит весь код из этого объектного файла.

В Windows существует два типа библиотек: статическая библиотека и библиотека импорта (обе называются .lib). Статическая библиотека похожа на файл Unix .a: она содержит код, который при необходимости включается в программу. Библиотека импорта, по сути, нужна только для того, чтобы подтвердить компоновщику допустимость некоторого идентификатора и его наличие в программе после загрузки DLL. Поэтому компоновщик использует сведения из библиотеки импорта для создания таблицы поиска идентификаторов, не включённых в DLL. При компоновке приложения или DLL может быть создана библиотека импорта, которую потребуется использовать для всех будущих DLL, зависящих от символов приложения или DLL.

Предположим, вы создаёте два динамически загружаемых модуля B и C, которым нужно совместно использовать другой блок кода A. В Unix вы не стали бы передавать A.a компоновщику для B.so и C.so: это привело бы к двойному включению кода, и у B и C появилась бы собственная копия. В Windows сборка A.dll также создаст A.lib. Компоновщику для B и C нужно передать A.lib. A.lib не содержит кода; в нём есть только информация, которая будет использоваться во время выполнения для доступа к коду A.

В Windows использование библиотеки импорта чем-то похоже на использование import spam: оно даёт доступ к именам spam, но не создаёт отдельную копию. В Unix компоновка с библиотекой больше похожа на from spam import *: она действительно создаёт отдельную копию.

Py_NO_LINK_LIB

Отключает неявную привязку к библиотеке Python на основе #pragma, выполняемую в заголовочных файлах CPython.

Добавлено в версии 3.14.

5.3. Практическое использование DLL

Python для Windows собирается с помощью Microsoft Visual C++; работа других компиляторов не гарантируется. Остальная часть этого раздела посвящена MSVC++.

При создании DLL в Windows библиотеку CPython можно использовать двумя способами:

  1. По умолчанию включение PC/pyconfig.h напрямую или через Python.h запускает неявную компоновку с библиотекой с учётом параметров конфигурации. Заголовочный файл выбирает pythonXY_d.lib для отладочной сборки, pythonXY.lib для выпуска и pythonX.lib для выпуска с включённым ограниченным API.

    Чтобы собрать две DLL — spam и ni (которая использует функции C из spam), — можно выполнить следующие команды:

    cl /LD /I/python/include spam.c
    cl /LD /I/python/include ni.c spam.lib
    

    Первая команда создала три файла: spam.obj, spam.dll и spam.lib. Spam.dll не содержит функций Python (например, PyArg_ParseTuple()), но благодаря неявно подключённому pythonXY.lib знает, как найти код Python.

    Вторая команда создала ni.dll (а также .obj и .lib), которая знает, как найти необходимые функции в spam, а также в исполняемом файле Python.

  2. Вручную, определив макрос Py_NO_LINK_LIB перед включением Python.h. Компоновщику необходимо передать pythonXY.lib.

    Чтобы собрать две DLL — spam и ni (которая использует функции C из spam), — можно выполнить следующие команды:

    cl /LD /DPy_NO_LINK_LIB /I/python/include spam.c ../libs/pythonXY.lib
    cl /LD /DPy_NO_LINK_LIB /I/python/include ni.c spam.lib ../libs/pythonXY.lib
    

    Первая команда создала три файла: spam.obj, spam.dll и spam.lib. Spam.dll не содержит функций Python (например, PyArg_ParseTuple()), но благодаря pythonXY.lib знает, как найти код Python.

    Вторая команда создала ni.dll (а также .obj и .lib), которая знает, как найти необходимые функции в spam, а также в исполняемом файле Python.

Не все идентификаторы экспортируются в таблицу поиска. Чтобы другие модули (в том числе Python) могли видеть ваши идентификаторы, необходимо указать _declspec(dllexport), как в void _declspec(dllexport) initspam(void) или PyObject _declspec(dllexport) *NiGetSpamData(void).

Developer Studio добавит множество библиотек импорта, которые на самом деле не нужны, увеличив размер исполняемого файла примерно на 100 КБ. Чтобы избавиться от них, откройте диалоговое окно Project Settings, вкладку Link, и укажите параметр игнорировать библиотеки по умолчанию. Добавьте в список подходящий msvcrtxx.lib.

© 2001 Python Software Foundation
Licensed under the PSF License.
https://docs.python.org/3.14/extending/windows.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API