Простое расширение с классом C++

prostoe rasshirenie s klassom c Интеграция Python/C

Чтобы увидеть, как все это работает, нам нужен класс C++. Для иллюстрации напишем простой класс, который будет использоваться в сценариях Python. Чтобы понимать, о чем рассказывается в этом разделе, вам необходимо знать язык C++. SWIG поддерживает расширенные возможности языка C++ (включая шаблоны и перегрузку функций и операторов), но для иллюстрации я постарался сохранить этот пример максимально простым. В следующих файлах C++ определен класс Number с четырьмя методами (add, sub, square и display), переменной класса (data), конструктором и деструктором. В примере 20.14 представлен заголовочный файл.

Пример 20.14. PP4E\Integrate\Extend\Swig\Shadow\number.h class Number { public:

Number(int start); // конструктор

подпись: // //подпись: //
//
подпись: деструктор изменяет член dataподпись: возвращает значение выводит член data~Number();

void add(int value);

void sub(int value); int square();

void display();

int data;

};

В примере 20.15 представлена реализация класса C++. При вызове большинства методов выводится сообщение трассировки операций класса. Обратите внимание, что для этого используется функция printf вместо типичного для C++ объекта cout. Когда-то таким способом решалась проблема смешивания вывода через cout в C++ и стандартный поток вывода в Python 2.X в Cygwin. Возможно в настоящее время в этом нет необходимости — из-за того, что система вывода в Python 3.X с включенной буферизацией может произвольно смешиваться с выводом из C++, в C++ обычно желательно принудительно выталкивать содержимое потока вывода (вызовом fflush(stdout) или cout<<flush), чтобы при выводе он не смешивался с текстом, в конце которого отсутствует символ перевода строки. Довольно странная, но вполне типичная особенность, когда смешиваются несопоставимые языковые системы.

Пример 20.15. PP4E\Integrate\Extend\Swig\Shadow\number.cxx

/////////////////////////////////////////////////////////////////////

// реализация класса C++, который, возможно, будет использоваться

// из программного кода Python;

// предупреждение: обычно оба приема вывода, через cout и print,

// работают, но я столкнулся с проблемой при смешивании

// вывода C++/Python в Cygwin, которая была решена с помощью printf /////////////////////////////////////////////////////////////////////

#include "number.h"

#include "stdio.h" // вместо #include "iostream.h"

Number::Number(int start) {

data = start; // вывод из python поступает в stdout

printf("Number: %d\n", data); // или: cout << "Number: " << data << endl;

}

Number::~Number() {

printf("~Number: %d\n", data);

}

void Number::add(int value) { data += value;

printf("add %d\n", value);

}

void Number::sub(int value) { data -= value;

printf("sub %d\n", value);

}

int Number::square() { return data * data; // после вывода, fflush(stdout) // или cout << flush

}

void Number::display() { printf("Number=%d\n", data);

}

Чтобы вы могли сравнить языки, ниже показано, как этот класс используется в программе C++. Программа в примере 20.16 создает объект Number, вызывает его методы, напрямую извлекает и устанавливает его атрибут данных (в C++ делается различие между «членами» и «методами», в то время как в Python те и другие обычно называют «атрибутами»).

Пример 20.16. PP4E\Integrate\Extend\Swig\Shadow\main.cxx

#include "iostream.h"

#include "number.h"

main()

{

Number *num; int res, val;

num = new Number(1); // создать экземпляр класса C++

num->add(4); // вызвать его методы

num->display();

num->sub(2);

num->display();

res = num->square(); // метод возвращает значение cout << "square: " << res << endl;

num->data = 99; // установить значение члена data C++

val = num->data; // получить значение члена data C++ cout << "data: " << val << endl;

cout << "data+1: " << val + 1 << endl;

num->display();

cout << num << endl; // вывести значение указателя на экземпляр delete num; // вызвать деструктор

}

Чтобы скомпилировать этот программный код в Cygwin (или в Linux) в выполняемый файл, можно использовать компилятор C++ командной строки g++. Если вы используете иную систему, вам придется импровизировать — между разными компиляторами C++ слишком много различий, чтобы их здесь перечислять. Введите команду компиляции непосредственно или укажите цель cxxtest в представленном выше make-файле, находящемся в каталоге с этим примером, и затем запустите вновь созданную программу C++:

/PP4E/Integrate/Extend/Swig/Shadow$ make -f makefile.number-swig cxxtest g++ main.cxx number.cxx -Wno-deprecated

/PP4E/Integrate/Extend/Swig/Shadow$ ./a.exe Number: 1 add 4 Number=5 sub 2 Number=3 square: 9 data: 99

data+1: 100 Number=99 0xe502c0 ~Number: 99

Использованная литература:

Марк Лутц — Программирование на Python, 4-е издание, II том, 2011

Каталог сайтов Всего.ру
Оцените статью
Секреты программирования
Добавить комментарий