Документация Python неофициальный перевод

windows.md

77 строк · 12.6 КБ · обычная страница · сырой текст · скачать

1> **Источник:** https://python-all.ru/3/extending/windows.html2>3> «Документация Python на русском» – неофициальный перевод официальной документации Python: версии от 2.6 до 3.16, полнотекстовый поиск, английский оригинал рядом с переводом. Эта Markdown-версия страницы предназначена для работы с LLM: вставьте её в ChatGPT, Claude или Cursor.45---67# 5. Сборка расширений C и C++ на Windows89В этой главе кратко объясняется, как создать модуль расширения для Windows на Python с помощью Microsoft Visual C++, после чего приводится более подробная справочная информация о том, как это работает. Материал полезен как программисту Windows, осваивающему сборку расширений Python, так и программисту Unix, заинтересованному в создании программного обеспечения, которое успешно собирается как на Unix, так и на Windows.1011Авторам модулей рекомендуется использовать подход distutils для сборки модулей расширения вместо описанного в этом разделе. При этом всё равно понадобится компилятор C, который использовался для сборки Python; обычно это Microsoft Visual C++.1213> **Примечание**14>15> В этой главе упоминается ряд имен файлов, содержащих закодированный номер версии Python. Эти имена файлов представлены с номером версии, показанным как `XY`; на практике `'X'` будет номером мажорной версии, а `'Y'` – номером минорной версии выпуска Python, с которым вы работаете. Например, если вы используете Python 2.2.1, `XY` на самом деле будет `22`.1617## 5.1. Подход с рецептами1819Существует два подхода к сборке модулей расширения в Windows, как и в Unix: использовать пакет `setuptools` для управления процессом сборки или делать всё вручную. Подход setuptools хорошо работает для большинства расширений; документация по использованию `setuptools` для сборки и упаковки модулей расширения доступна в [Сборка расширений C и C++ с помощью setuptools](https://python-all.ru/3/extending/building.html#setuptools-index). Если вы обнаружите, что вам действительно нужно делать всё вручную, может быть полезно изучить файл проекта для модуля стандартной библиотеки [winsound](https://python-all.ru/src/3.14/PCbuild/winsound.vcxproj).2021## 5.2. Различия между Unix и Windows2223В Unix и Windows используются совершенно разные парадигмы загрузки кода во время выполнения. Прежде чем пытаться собрать модуль, который может загружаться динамически, следует понимать, как работает ваша система.2425В Unix файл shared object (`.so`) содержит код, который будет использоваться программой, а также имена функций и данных, которые он ожидает найти в программе. Когда файл присоединяется к программе, все ссылки на эти функции и данные в коде файла изменяются так, чтобы указывать на фактические адреса в памяти программы, где размещены функции и данные. По сути, это операция компоновки.2627В Windows файл динамически подключаемой библиотеки (`.dll`) не содержит висячих ссылок. Вместо этого доступ к функциям и данным осуществляется через таблицу поиска. Таким образом, код DLL не требует исправлений во время выполнения для ссылок на память программы; вместо этого код уже использует таблицу поиска DLL, а таблица поиска изменяется во время выполнения, чтобы указывать на функции и данные.2829В Unix существует только один тип файла библиотеки (`.a`), который содержит код из нескольких объектных файлов (`.o`). На этапе компоновки для создания shared object файла (`.so`) компоновщик может обнаружить, что не знает, где определен идентификатор. Компоновщик будет искать его в объектных файлах библиотек; если найдет, он включит весь код из этого объектного файла.3031В Windows существует два типа библиотек: статическая библиотека и библиотека импорта (обе называются `.lib`). Статическая библиотека похожа на файл Unix `.a`; она содержит код, который включается по мере необходимости. Библиотека импорта в основном используется только для того, чтобы заверить компоновщик, что определенный идентификатор допустим и будет присутствовать в программе при загрузке DLL. Таким образом, компоновщик использует информацию из библиотеки импорта для построения таблицы поиска для идентификаторов, не включенных в DLL. Когда приложение или DLL компонуется, может быть создана библиотека импорта, которую потребуется использовать для всех будущих DLL, зависящих от символов в этом приложении или DLL.3233Предположим, вы создаете два модуля динамической загрузки, B и C, которые должны совместно использовать другой блок кода A. В Unix вы бы *не* передавали `A.a` компоновщику для `B.so` и `C.so`; это привело бы к его включению дважды, так что B и C получили бы по собственной копии. В Windows сборка `A.dll` также приводит к сборке `A.lib`. Вы *именно* передаете `A.lib` компоновщику для B и C. `A.lib` не содержит кода; он содержит только информацию, которая будет использоваться во время выполнения для доступа к коду A.3435В Windows использование библиотеки импорта похоже на использование `import spam`; она дает доступ к именам из spam, но не создает отдельной копии. В Unix компоновка с библиотекой больше похожа на `from spam import *`; она создает отдельную копию.3637#### `Py_NO_LINK_LIB`3839Отключает неявную компоновку через `#pragma` с библиотекой Python, выполняемую внутри заголовочных файлов CPython.4041Добавлено в версии 3.14.4243## 5.3. Использование DLL на практике4445Python для Windows собирается в Microsoft Visual C++; использование других компиляторов может как работать, так и нет. Остальная часть этого раздела относится только к MSVC++.4647При создании DLL в Windows можно использовать библиотеку CPython двумя способами:48491. По умолчанию включение `PC/pyconfig.h` напрямую или через `Python.h` запускает неявную, учитывающую конфигурацию компоновку с библиотекой. Заголовочный файл выбирает `pythonXY_d.lib` для Debug, `pythonXY.lib` для Release и `pythonX.lib` для Release с включенным [Ограниченным API](https://python-all.ru/3/c-api/stable.html#stable-application-binary-interface).5051   Чтобы собрать две DLL, spam и ni (которая использует функции C из spam), можно использовать следующие команды:5253   ```c54   cl /LD /I/python/include spam.c55   cl /LD /I/python/include ni.c spam.lib56   ```5758   Первая команда создала три файла: `spam.obj`, `spam.dll` и `spam.lib`. `Spam.dll` не содержит никаких функций Python (например, [`PyArg_ParseTuple()`](https://python-all.ru/3/c-api/arg.html#c.PyArg_ParseTuple)), но благодаря неявно скомпонованной `pythonXY.lib` умеет находить код Python.5960   Вторая команда создала `ni.dll` (а также `.obj` и `.lib`), который умеет находить необходимые функции из spam, а также из исполняемого файла Python.612. Вручную – определив макрос [`Py_NO_LINK_LIB`](https://python-all.ru/3/extending/windows.html#c.Py_NO_LINK_LIB) перед включением `Python.h`. Необходимо передать `pythonXY.lib` компоновщику.6263   Чтобы собрать две DLL, spam и ni (которая использует функции C из spam), можно использовать следующие команды:6465   ```c66   cl /LD /DPy_NO_LINK_LIB /I/python/include spam.c ../libs/pythonXY.lib67   cl /LD /DPy_NO_LINK_LIB /I/python/include ni.c spam.lib ../libs/pythonXY.lib68   ```6970   Первая команда создала три файла: `spam.obj`, `spam.dll` и `spam.lib`. `Spam.dll` не содержит никаких функций Python (например, [`PyArg_ParseTuple()`](https://python-all.ru/3/c-api/arg.html#c.PyArg_ParseTuple)), но благодаря `pythonXY.lib` умеет находить код Python.7172   Вторая команда создала `ni.dll` (а также `.obj` и `.lib`), который умеет находить необходимые функции из spam, а также из исполняемого файла Python.7374Не каждый идентификатор экспортируется в таблицу поиска. Если вы хотите, чтобы другие модули (включая Python) могли видеть ваши идентификаторы, необходимо указать `_declspec(dllexport)`, например `void _declspec(dllexport) initspam(void)` или `PyObject _declspec(dllexport) *NiGetSpamData(void)`.7576Developer Studio добавит много библиотек импорта, которые на самом деле не нужны, увеличив размер исполняемого файла примерно на 100 КБ. Чтобы избавиться от них, в диалоговом окне Project Settings на вкладке Link следует указать *ignore default libraries*. Затем добавить правильную `msvcrtxx.lib` в список библиотек.77