Добрый день. Я сейчас прохожу курс повышения квалификации - "Профессиональное веб-программирование". Мне нужно получить диплом по этому курсу. Я так полагаю нужно его оплатить чтобы получить диплом о повышении квалификации. Как мне оплатить этот курс?
|
Интеграция Python с другими языками программирования
Использование SWIG
SWIG (Simplified Wrapper and Interface Generator, упрощенный упаковщик и генератор интерфейсов) - это программное средство, сильно упрощающее (во многих случаях - автоматизирующее) использование библиотек, написанных на C и C++, а также на других языках программирования, в том числе (не в последнюю очередь!) на Python. Нужно отметить, что SWIG обеспечивает достаточно полную поддержку практически всех возможностей C++, включая предобработку, классы, указатели, наследование и даже шаблоны C++. Последнее очень важно, если необходимо создать интерфейс к библиотеке шаблонов.
Пользоваться SWIG достаточно просто, если уметь применять компилятор и компоновщик (что в любом случае требуется при программировании на C/C++).
Простой пример использования SWIG
Предположим, что есть программа на C, реализующая некоторую функцию (пусть это будет вычисление частоты появления различных символов в строке):
/* File : freq.c */ #include <stdlib.h> int * frequency(char s[]) { int *freq; char *ptr; freq = (int*)(calloc(256, sizeof(int))); if (freq != NULL) for (ptr = s; *ptr; ptr++) freq[*ptr] += 1; return freq; }
Для того чтобы можно было воспользоваться этой функцией из Python, нужно написать интерфейсный файл (расширение .i) примерно следующего содержания:
/* File : freq.i */ %module freq %typemap(out) int * { int i; $result = PyTuple_New(256); for(i=0; i<256; i++) PyTuple_SetItem($result, i, PyLong_FromLong($1[i])); free($1); } extern int * frequency(char s[]);
Интерфейсные файлы содержат инструкции самого SWIG и фрагменты C/C++-кода, возможно, с макровключениями (в примере выше: $result, $1 ). Следует заметить, что для преобразования массива целых чисел в кортеж элементов типа long, необходимо освободить память из-под исходного массива, в котором подсчитывались частоты.
Теперь (подразумевая, что используется компилятор gcc), создание модуля расширения может быть выполнено примерно так:
swig -python freq.i gcc -c -fpic freq_wrap.c freq.c -DHAVE_CONFIG_H -I/usr/local/include/python2.3 -I/usr/local/lib/python2.3/config gcc -shared freq.o freq_wrap.o -o _freq.so
После этого в рабочем каталоге появляется файлы _freq.so и freq.py, которые вместе и дают доступ к требуемой функции:
>>> import freq >>> freq.frequency("ABCDEF")[60:75] (0L, 0L, 0L, 0L, 0L, 1L, 1L, 1L, 1L, 1L, 1L, 0L, 0L, 0L, 0L)
Помимо этого, можно посмотреть на содержимое файла freq_wrap.c, который был порожден SWIG: в нем, среди прочих вспомогательных определений, нужных самому SWIG, можно увидеть что-то подобное проиллюстрированному выше примеру модуля md5. Вот фрагмент этого файла с определением обертки для функции frequency():
extern int *frequency(char []); static PyObject *_wrap_frequency(PyObject *self, PyObject *args) { PyObject *resultobj; char *arg1 ; int *result; if(!PyArg_ParseTuple(args,(char *)"s:frequency",&arg1)) goto fail; result = (int *)frequency(arg1); { int i; resultobj = PyTuple_New(256); for(i=0; i<256; i++) PyTuple_SetItem(resultobj, i, PyLong_FromLong(result[i])); free(result); } return resultobj; fail: return NULL; }
В качестве упражнения, предлагается сопоставить это определение с файлом freq.i и понять, что происходит внутри функции _wrap_frequency(). Подсказка: можно посмотреть еще раз комментарии к C-коду модуля md5.
Стоит еще раз напомнить, что в отличие от Python, в языке C/C++ управление памятью должно происходить в явном виде. Именно поэтому добавлена функция free() при преобразовании типа. Если этого не сделать, возникнут утечки памяти. Эти утечки можно обнаружить, при многократном выполнении функции:
>>> import freq >>> for i in xrange(1000000): ... dummy = freq.frequency("ABCDEF") >>>
Если функция freq.frequency() имеет утечки памяти, выполняемый процесс очень быстро займет всю имеющуюся память.