Главная » Статьи » Учебник: практика

Написание расширений Python-а на C. Начало. (Для пользователей Windows / Visual С++)
Предисловие
Начнем с того, что в настоящий момент я - начинающий "питонщик" и довольно опытный "си-шник". В частности, Питон привлек меня как раз возможностью самостоятельно писать под него C-расширения. Позже я познакомился с Panda3D и мой интерес к этому языку возрос многократно. Но начинать освоение я решил все же не с углубленного изучения Питона, а с попытки написать какое-нибудь хотя бы самое простое расширение на C. В принципе, его даже и писать-то не надо, оно входит в комплект исходников Питона, а вот здесь расписано, как все просто и легко собирается, ставится и запускается. Просто, да непросто. Набрать или скопипастить C-код действительно не представляет никакого труда. Разобраться в тонкостях реализации - тоже можно. Собрать проект и получить dll-ку не трудно. Вопрос - что делать со всем этим добром дальше? Как скормить его Питону? Открываем вот эту страничку и учимся писать установочный скрипт. Этому скрипту скармливаем наш исходник на C и вуа-ля - расширение собрано и установлено. Подключается в *.py через стандартный import, на вызов foo() пишет "Hello, world". Есть только одна маленькая проблема: расширение, ежели таковое придется писать, будет куда больше пяти строк и гораздо сложнее HelloWorld-а, то есть явно нуждающееся в хорошей отладке. Выходит так, что выше приведенный пайплайн по созданию и установке расширения не устраивает нас категорически. Кроме того я лично привык писать и дебажить свои приложения в среде Visual Studio, какие-то standalone сборки cl-ем и дебаг через командную строку мне совсем душу не греют. Вобщем, начинаем рыть дальше. Цель - написание и сборка простого расширения "Hello World" из стандартного примера, и дебаг его вызова с помощью VC.

Выуживаем исходники Питона
Исходники Питона (к стати, для написания расширения для Panda3D 1.6.2 вам понадобятся исходники к Питону версии 2.5) доступны через SVN. Людям, знакомым с SVN, сообщаю, что исходники Питона 2.5 находятся по адресу http://svn.python.org/projects/python/branches/release25-maint, и дальше можете эту главу не читать smile Тех же, кто ни разу до этого не имел дела с системами контроля версий, эта штука может поставить в тупик. Веб-интерфейс позволяет выйти к искомым файлам и скачать их, но - поштучно (это при том, что общий объем исходников - около 30 мегабайт). Спешу утешить: ничего поштучно качать не надо. Идем вот сюда и скачиваем TortoiseSVN - это очень удобная визуальная среда для работы с SVN, выполненная в виде плагина к стандартному виндовому Проводнику. После установки она добавляет в контекстное меню Проводника подменю, через которое доступно большинство функций системы контроля версий. Для скачивания исходников нам понадобится всего одна из них smile
Пока качается и ставится наша "черепашка", скажу пару слов о том, что такое "система контроля версий". Это система синхронизации и серверного хранения рабочих материалов. Если вы пишете ваши программы в одиночку, эта штука вам вряд ли понадобится, а вот если командой, то обойтись без нее фактически невозможно, особенно если вы с коллегами одновременно работаете с одними и теми же файлами. Все внесенные вами изменения сохраняются системой контроля в виде так называемых патчей, с помощью которых ваши товарищи обновляют свою рабочую копию, чтобы получить ваши изменения. Система хранит всю цепочку изменений, таким образом пользователь может как получить самые свежие файлы, так и откатиться на несколько ревизий назад, чтобы посмотреть код до модификации. Кроме этого система позволяет делать ответвления от основной ветви разработки, в которых можно совершенно безбоязненно экспериментировать, не боясь испортить проект. Применительно к Питону можно отметить, что в настоящее время в основной ветке разработки (trunk) находятся исходники Python 2.7, интересующие же нас исходники версии 2.5 лежат в branches/release25-maint (не пугайтесь, сейчас все станет понятно :)).
И так, открываем Проводник, создаем в удобном месте папочку, где будут храниться питоновские исходники, кликаем по этой папочке правой кнопкой и в контекстном меню обнаруживаем новые пункты: SVN Checkout... и подменю TortoiseSVN. Нас интересует Checkout - эта команда проассоциирует указанную папку серверного хранилища с локальной папкой на вашей машине. Выбирайте этот пункт. Появится окошко, в верхней строке с названием URL of repository вводится адрес серверной папки - http://svn.python.org/projects/python/branches/release25-maint для папки исходников Питона версии 2.5 (к стати, нажав на кнопку с троеточием справа от строки вы сможете полазить по серверу и посмотреть, что еще интересного можно оттуда зачекаутить ;)). Строка ниже - адрес вашей локальной папки. Радиокнопку HEAD revision оставляем выбранной - это означает для SVN, что мы будем брать самую последнюю ревизию из репозитория. Все. Жмем Ok и наблюдаем, процесс синхронизации содержимого вашей локальной папки с содержимым папки серверной. Поскольку ваша локальная папка до этого была пуста, то синхронизация заключается в переписывании файлов с сервера на вашу машину, что нам, собственно, и нужно.
По окончании процесса вы получите кучу папок и файлов, отмеченных в проводнике зеленым кружочком с галочкой. Такая пометка означает, что локальный файл совпадает с файлом серверным по содержанию. Попробуйте внести любое изменение в любой файл, и он тут же сменит иконку на красный кружочек с восклицательным знаком, что свидетельствует о рассинхронизации с серверной версией файла. Кликните на этом файле правой кнопкой и из подменю TortoiseSVN выберите Revert... - файл "откатится" в предыдущее состояние, все ваши изменения исчезнут. Так же обратите внимание на функцию Update - она актуализирует вашу локальную копию в случае, если на сервере произошли какие-нибудь изменения (были сделаны новые ревизии). Пожалуй, это единственные функции кроме чекаута, которые могут вам пригодиться. Если вы не собираетесь больше выполнять над вашей папкой какие-либо функции SVN, или же вас раздражают красные и зеленые точки на файлах и папках, просто удалите все скрытые папки .svn с их содержимым.

Сборка
И так, питоновские исходники у нас в кармане. А зачем, собственно, они нам нужны? На самом деле нам нужны не столько исходники, сколько дебаг-версия Питона, которую мы и соберем, благо что уже готовый проект под VC6 лежит в папке *python*\PC\VC6 и называется pcbuild.dsw (здесь и далее под *python* будет подразумеваться папка, в которую вы зачекаутили исходники). В этом проекте вы найдете набор солюшенов для разных питоновских модулей. В принципе, для запуска нашего HelloWorld-а достаточно скомпилировать pythoncore и python. Проследите, чтобы сборка модулей шла в Debug конфигурации. Готовые файлы будут помещены в корневой каталог, то есть в *python*\PC\VC6, вы без труда найдете их по постфиксу *_d.*, что означает debug. Релизная сборка даст вам файлы без всяких постфиксов, точно такие же уже есть у вас в вашем релизе Python, идущем в составе дистрибутива Panda3D. Они не годятся для сборки и запуска дебаговых расширений - только для релизных. Запомните этот момент: для отладки вашего C-расширения вы должны использовать при сборке и запуске дебаговые либы и дебаговый же Питон (python_d.exe). Понятно, что и само расширение должно собираться в Debug конфигурации. После отладки вашего расширения, соберите его в конфигурации Release и сможете использовать с обычным Питоном (а вот с дебаговым уже не сможете :)).
Так, ну ладно, с Питоном разобрались. Переходим непосредственно к расширению. Простенький тестовый пример уже есть в наших исходниках, находится по адресу *python*\ PC\example_nt. Открываем, собираем. Если компилятор будет ругаться на отсутствие внешних имен, значит он просто не может найти нужные ему библиотеки. Пойдите в Tools > Options выберите Projects > VC++ Directories и добавьте в список Library files путь к вашим дебаговым питоновским либам (*python*\PC\VC6). После этого example должен собраться. Найдите в папке *python*\PC\example_nt\Debug файл example_d.pyd, это и есть наше расширение. Скопируйте его в *python*\PC\VC6 и запустите python_d.exe, введите:

>>> import example
[27563 refs]
>>> example.foo()
Hello, world
[27563 refs]

Если все сделано правильно, то результат будет подобен тому, что показан выше. Как видите, наш HelloWorld исправно отработал. Текст в квадратных скобках - отладочная информация, релизный Питон ее не отображает.

Дебаг с помощью VC
Теперь самое интересное: как нам подебажить наше расширение. Для начала давайте разберемся, что это за загадочный *.pyd мы получили. Открываем свойства проекта example (Project > Properties) переходим в General и выясняем, что собирали мы, оказывается, динамическую библиотеку .dll. Идем в Linker и смотрим Output File, в этой строке кроется разгадка имени нашего расширения: в качестве выходного файла тут указано имя example_d.pyd, то есть наш загадочный *.pyd не что иное, как переименованная dll-ка. Ну и славно, давайте ее дебажить. Для дебага dll-ки нам потребуется запускающая ее среда, ну и еще один момент: собранная нами библиотека должна располагаться по адресу *python*\PC\VC6 (куда мы ее только что скопировали вручную), для этого в настройках проекта изменим Output File: ..\VC6/example_d.pyd, теперь после сборки наш example_d.pyd будет сохраняться не в *python*\PC\example_nt\Debug, а непосредственно по месту назначения. Для запуска нашего расширения напишем программу в две строки:

import example
example.foo()

Сохраните ее в файл example.py, положите куда-нибудь, хоть в тот же *python*\PC\VC6.
Вернемся к настройкам проекта example и зададим вызывающую среду, разумеется, это будет наш дебаговый Питон. В настройках проекта перейдите к вкладке Debug, в строке Command укажите *python*\PC\VC6\python_d.exe. Но сам по себе Питон наше расширение не вызовет, его вызывает выше приведенная программа в две строки, которую исполняет Питон. Давайте дадим ему эту программу в качестве аргумента командной строки: в свойствах проекта в строке Command Arguments (следующая за Command) укажите путь к example.py (*python*\PC\VC6\example.py). Готово! Чтобы убедиться, что дебаг работает, поставьте брейкпоинт в любой из трех строк функции ex_foo(). Делаем Debug > Start и - УРА! - мы на брейкпоинте!

И так, что мы имеем в сухом остатке: у нас есть проект VC, реализующий пусть примитивное, но рабочее расширение для Python, которое собирается и дебажится в среде Visual Studio, а также примитивная программа на Питоне, которая это расширение использует. Отличное начало. Осталось лишь ознакомиться с форматом вызовов функций и прочими питоновскими соглашениями, в чем вам поможет документация. Удачи smile

Категория: Учебник: практика | Добавил: vcow (11.06.2009)
Просмотров: 9024 | Рейтинг: 4.0/3
Всего комментариев: 0
Добавлять комментарии могут только зарегистрированные пользователи.
[ Регистрация | Вход ]
Онлайн всего: 1
Гостей: 1
Пользователей: 0