Spec-Zone.ru › Python 3.8

Создание расширений 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. Пошаговый подход

Существует два подхода к построению модулей расширения на Windows, так же как и на Unix: использовать пакет distutils для управления процессом сборки или выполнять действия вручную. Подход distutils хорошо работает для большинства расширений; документация по использованию distutils для сборки и упаковки модулей расширения доступна в Распространение модулей Python (старая версия). Если вы обнаружите, что вам действительно нужно делать вещи вручную, изучение файла проекта модуля 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; оно предоставляет вам доступ к именам, но не создаёт отдельные копии. В Unix связывание с библиотекой больше похоже на from spam import *; оно создаёт отдельные копии.

5.3. Практическое применение DLL

Windows Python создаётся в Microsoft Visual C++; использование других компиляторов может работать или нет (хотя Borland, кажется, работает). Остальная часть этого раздела специфична для 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()), но она знает, как найти код Python благодаря pythonXY.lib.

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

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

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

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

Spec-Zone.ru

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