Как обычно, класс C++ можно импортировать в интерактивной оболочке и немного поэкспериментировать с ним — этот прием позволяет не только продемонстрировать здесь некоторые важные особенности, но и протестировать обернутые классы C++ в интерактивном сеансе Python:
…/PP4E/Integrate/Extend/Swig/Shadow$ python
> >> import _number
> >> _number.__file__ # класс C++ плюс сгенерированный связующий модуль
‘_number.dll’
> >> import number # сгенерированный модуль Python теневого класса
> >> number.__file__
‘number.py’
> >> x = number.Number(2) # создать экземпляр класса C++ в Python Number: 2
> >> y = number.Number(4) # создать еще один объект C++ Number: 4
> >> x, y
(<number.Number; proxy of <Swig Object of type ‘Number *’ at 0x7ff4bcf8> >, <number.Number; proxy of <Swig Object of type ‘Number *’ at 0x7ff4b998> >)
> >> x.display() # вызвать метод C++ (как в C++: x->display()) Number=2
> >> x.add(y.data) # извлечь значение члена data в C++, вызвать метод C++ add 4
> >> x.display()
Number=6
> >> y.data = x.data + y.data + 32 # присвоить значение члену data в C++
> >> y.display() # y хранит указатель C++ ‘this‘
Number=42
> >> y.square() # метод с возвращаемым значением
1764
> >> t = y.square()
> >> t, type(t) # в Python 3.X типы — это классы
(1764, <class ‘int‘>)
Естественно, в этом примере используется очень маленький класс C++, только чтобы подчеркнуть основные моменты, но даже на этом уровне прозрачность интеграции Python/C++, которую обеспечивает SWIG, восхищает. Программный код Python использует члены и методы класса C++, как если бы они были реализованы на языке Python. Кроме того, такая же прозрачность интеграции сохраняется и при переходе к использованию более реалистичных библиотек классов C++.
Так чего же мы добились? На данный момент ничего особенного, но если всерьез начать пользоваться SWIG, то самым большим недостатком может оказаться отсутствие на сегодняшний день в SWIG поддержки всех особенностей C++. Если в классах используются довольно сложные особенности C++ (а их достаточно много), то может потребоваться создать для SWIG упрощенные описания типов классов, а не просто запускать SWIG с исходными заголовочными файлами классов, поэтому вам обязательно следует ознакомиться с руководством по SWIG и с информацией на сайте проекта, чтобы получить больше подробностей по этой и другим темам.
Однако в обмен на такие компромиссы SWIG может полностью исключить необходимость вручную писать связующие слои для доступа к библиотекам C и C++ из сценариев Python. Если вам доводилось когда-либо писать такой программный код вручную, вам должно быть ясно, что это очень большой выигрыш.
Если же вы пойдете путем работы вручную, обратитесь к стандартным руководствам Python по расширению за дополнительными сведениями по вызовам API, используемым в этой главе, а также к дополнительным инструментам создания расширений, о которых мы не имеем возможности рассказывать в этой книге. Расширения на C могут лежать в широком диапазоне от коротких входных файлов SWIG до программного кода, крепко связанного с внутренним устройством интерпретатора Python. Практика показывает, что первые из них переносят разрушительное действие времени значительно лучше, чем вторые.
Использованная литература:
Марк Лутц — Программирование на Python, 4-е издание, II том, 2011