Блог
  • Начало
  • Обо мне
  • Обратная связь

Создание модуля Python на C++ с помощью SWIG

Дата и время: 8 июня 2014 г. 1:33 | Категория: Программирование, 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
Select language:
  • Русский
  • English

  • Программирование

    Python C++ JavaScript

    Веб-разработка

    Django ASP.NET

    Мобильная разработка

    Windows Phone Android

    Разработка игр

    Unity3d Blender

    Артем Устимов © 2014