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

windows.md

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

1> **Источник:** https://python-all.ru/3.10/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, есть два подхода к сборке модулей расширения: использовать пакет [`distutils`](https://python-all.ru/3.10/library/distutils.html#module-distutils) для управления процессом сборки или делать всё вручную. Подход distutils хорошо подходит для большинства расширений; документация по использованию [`distutils`](https://python-all.ru/3.10/library/distutils.html#module-distutils) для сборки и упаковки модулей расширения доступна в [Distributing Python Modules (Legacy version)](https://python-all.ru/3.10/distutils/index.html#distutils-index). Если вы обнаружите, что действительно нужно делать всё вручную, полезно будет изучить файл проекта для модуля стандартной библиотеки [winsound](https://python-all.ru/src/3.10/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## 5.3. Использование DLL на практике3839Python для Windows собирается в Microsoft Visual C++; использование других компиляторов может как работать, так и нет. Остальная часть этого раздела относится только к MSVC++.4041При создании DLL в Windows необходимо передать компоновщику `pythonXY.lib`. Чтобы собрать две DLL, spam и ni (которая использует функции C из spam), можно использовать следующие команды:4243```c44cl /LD /I/python/include spam.c ../libs/pythonXY.lib45cl /LD /I/python/include ni.c spam.lib ../libs/pythonXY.lib46```4748Первая команда создала три файла: `spam.obj`, `spam.dll` и `spam.lib`. `Spam.dll` не содержит функций Python (таких как [`PyArg_ParseTuple()`](https://python-all.ru/3.10/c-api/arg.html#c.PyArg_ParseTuple)), но знает, как найти код Python благодаря `pythonXY.lib`.4950Вторая команда создала `ni.dll` (а также `.obj` и `.lib`), которая знает, как найти необходимые функции из spam, а также из исполняемого файла Python.5152Не каждый идентификатор экспортируется в таблицу поиска. Если вы хотите, чтобы другие модули (включая Python) могли видеть ваши идентификаторы, необходимо указать `_declspec(dllexport)`, например `void _declspec(dllexport) initspam(void)` или `PyObject _declspec(dllexport) *NiGetSpamData(void)`.5354Developer Studio добавит много библиотек импорта, которые на самом деле не нужны, увеличив размер исполняемого файла примерно на 100 КБ. Чтобы избавиться от них, в диалоговом окне Project Settings на вкладке Link следует указать *ignore default libraries*. Затем добавить правильную `msvcrtxx.lib` в список библиотек.55