Spec-Zone.ru › Python 3.13

Создание расширений C и C++ в Windows

В этой главе кратко объясняется, как создать модуль расширения для Windows на Python с помощью 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. Практический подход

Как и в Unix, в Windows есть два подхода к сборке модулей расширения: использовать пакет 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). Статическая библиотека похожа на файл .a в Unix: она содержит код, который включается по мере необходимости. Библиотека импорта используется в основном для того, чтобы сообщить компоновщику, что определённый идентификатор допустим и будет присутствовать в программе при загрузке DLL. Поэтому компоновщик использует сведения из библиотеки импорта для создания таблицы поиска идентификаторов, не включённых в DLL. При компоновке приложения или DLL может быть создана библиотека импорта, которую потребуется использовать для всех последующих DLL, зависящих от символов приложения или DLL.

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

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

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

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

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

cl /LD /I/python/include spam.c ../libs/pythonXY.lib
cl /LD /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–2025 Python Software Foundation
Licensed under the PSF License.
https://docs.python.org/3.13/extending/windows.html

Spec-Zone.ru

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