Создание модуля Python на C++ с помощью SWIG
Date and time: June 8, 2014, 1:33 a.m. | Category: Программирование, Python, C++
В данной статье будет рассмотрен процесс создания небольшого модуля для Python, состоящего из одного класса и одной функции, написанных на языке C++. Данная задача реализуется с использованием интерфейса SWIG (Simplified Wrapper and Interface Generator), позволяющего сгенерировать прослойку логики между кодом C++ и Python.
Реализация модуля в данной статье рассматривается под управлением ОС Windows. Для продолжения Вам понадобиться SWIG и компилятор GCC, который для Windows можно скачать здесь (также он может быть в комплекте с Qt). Для работоспособности используемых команд не забудьте указать директории с файлами g++.exe и swig.exe в переменной окружения PATH.
Опишем в заголовочном файле cube.h простейший класс Cube и прототип функции getArea:
class Cube
{
public:
int a;
Cube();
Cube(int a);
int getVolume();
};
int getArea(Cube cube);
Класс представляет собой абстракцию куба, с единственным полем a - длиной стороны куба и единственным методом getVolume - методом получения объёма куба. Также отдельно описан прототип функции getArea, который принимает объект куба и возвращает площадь его стороны.
В файле cube.cxx опишем реализацию функции, конструкторов и метода класса:
#include "cube.h"
Cube::Cube()
{
/* Empty */
}
Cube::Cube(int a)
{
this->a = a;
}
int Cube::getVolume()
{
return this->a * this->a * this->a;
}
int getArea(Cube cube)
{
return cube.a * cube.a;
}
Для того, чтобы дать понять SWIG какие файлы использовать, нужно описать следующий связующий файл cube.i:
%module cube
%{
#include "cube.h"
%}
%include cube.h
В параметре %module указывается название модуля, которое будет использоваться при импортировании из кода Python. Между %{ и %} указываются заголовочные файлы с описанием сигнатур классов и функций. %include cube.h показывает, что необходимо использовать все сигнатуры из cube.h. Также можно указать отдельно несколько используемых сигнатур, например:
%module cube
%{
#include "cube.h"
%}
int getArea(Cube cube);
Тогда из заголовочного файла в модуль будет включена только функция getArea.
Сгенерируем слой связующей логики между Python и C++. Для этого из консоли, находясь в директории с созданными файлами, выполните команду
swig -c++ -python cube.i
В результате в директории будут созданы два файла: cube_wrap.cxx и cube.py. Далее необходимо скомпилировать написанный на C++ модуль:
g++ -c cube.cxx
g++ -c cube_wrap.cxx -I C:\Python27\include
g++ -shared cube_wrap.o cube.o -o _cube.pyd -L C:\Python27\libs -l python27
Где вместо C:\Python27 укажите путь к Вашей версии Python, а вместо python27 версию Вашего объектного модуля Python (он находится в папке libs).
Полученные файлы cube.py и _cube.pyd являются компонентами модуля. Если скопировать их в папку с Python или в папку, находящуюся в пути поиска модулей, то cube можно импортировать и использовать как любой другой модуль Python:
>>> import cube
>>> c = cube.Cube(5)
>>> c.getVolume()
125
>>> cube.getArea(c)
25
>>>
Более подробную информацию, а также информацию по созданию модуля в среде Linux можно найти в документации SWIG.
Скачать архив с полученными в данной статье файлами: cube.zip comments powered by Disqus