Упаковка C/C++ для Python с использованием SWIG — Set 1

| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |

Нет никаких сомнений в том, что Numpy, так быстро и эффективно выполняет огромное количество задания ? На самом деле такие библиотеки, как Numpy, не написаны полностью на Python, некоторые части библиотеки написаны на C, что обеспечивает лучшую производительность. После написания кода C мы оборачиваем их в код Python, который действует как интерфейс для этих кодов C. Затем мы можем вызывать функции C, используя синтаксис Python, где фактическая обработка выполняется в C за кулисами, а результат возвращается обратно в виде объекта Python. В этой статье мы увидим, как создать оболочку Python для нашей программы C в системах Linux с помощью программного обеспечения SWIG .

Что такое SWIG

Короче говоря, SWIG — это компилятор, который принимает объявления C/C++ и оборачивает их для доступа к этим объявлениям из других языков, таких как Python, Tcl, Ruby и т. д.
Обычно это не требует каких-либо изменений в существующем коде и создает интерфейс. в течение минуты.

Причины создания оболочки

Во многих случаях нам нужны оболочки, следующие: —

  • Создание интерпретируемого интерфейса для существующих программ на C.
  • Создание высокопроизводительных модулей C для языков сценариев ‚Äã‚Äã
  • Тестирование огромных программ C очень сложно, поэтому мы пишем оболочки на некоторых языках сценариев, таких как Python, где это очень легко писать тесты. и т. д.

Установка SWIG

Чтобы загрузить SWIG непосредственно из репозитория apt, введите следующие команды —

sudo apt-get update sudo apt-get install swig 

Написание оболочки с помощью SWIG

Давайте рассмотрим этот фрагмент кода на C с двумя функциями и одной глобальной переменной —


/ * file: gfg.c * /


# include "stdio.h >
# include "математика.h >


// наш заголовочный файл
# include "gfg.h"
# определить ll long long


double myvar = 3.4;


// вычисление факториала

ll int fact (ll int п)

{

if (n "= 1)

return 1;

else

возврат (n * факт (n-1));

}


// найти мод

int my_mod ( int n, int m )

{/code>

return (n% m);

}

Вот наш заголовочный файл — ;


long long int fact ( long long int n);

int my_mod ( int n, int m);

Сначала мы должны создать файл интерфейса SWIG . Этот файл содержит прототипы функций ANSI C и объявления переменных. Здесь —

  • Директива % module указывает имя модуля, который мы будем использовать в Python.
  • % {. . % } предоставляет место для вставки дополнительного кода, например файлов заголовков C или дополнительных объявлений C, в сгенерированный код оболочки.
  • Директива % include позволяет нам включать дополнительные файлы, такие как файлы заголовков.

/ * файл: gfg.i * /


/ * имя используемого модуля * /
% module gfg
% {

/ * Все в этом файле копируется в

файл-обертка. Включите требуемый заголовочный файл C

скомпилируйте интерфейс * /

# include "gfg.h"

/ * объявление переменной * /

double myvar;

%}


/ * явный список функций и переменных для взаимодействия * /

double myvar;

long long int fact ( long long int n1);

int my_mod ( int m, int n);


/ * или если мы хотим связать все функции, то можем просто

включает такой заголовочный файл -

% include & quot; gfg.h"

* /

Теперь мы создадим код оболочки с помощью такой команды, как

$ swig -python gfg.i 

Эта команда создает код оболочки с именем "gfg_wrap.c" . Эти файлы содержат раздутую версию нашего исходного кода C с другим кодом обработки ошибок и т. д. Сгенерирован еще один файл "gfg.py", являющийся модулем, который мы импортируем в наш python.


После этого нам нужно сгенерировать позиционно-независимый код для использования в общей библиотеке путем компиляции "gfg_wrap.c" и "gfg .c" следующей командой:

$ gcc -c -fpic gfg_wrap.c gfg.c -I /use/include/python2.7 

Заменить python2 .7 с вашей версией Python. Это создаст два объектных файла
"Gfg_wrap.o‚" и "gfg.o‚" . В приведенной выше команде —

  • сгенерируйте позиционно-независимый код (PIC), подходящий для использования в общей библиотеке, если он поддерживается для целевой машины. Этот код получает доступ ко всем постоянным адресам через глобальную таблицу смещений (GOT)

Примечание: если вы получаете сообщение об ошибке, такое как следующие возможные причины —

  • Возможно, у вас нет ' Python.h ' или
  • Вы вводите неверное местоположение ' Python.h ' для компилятора

Чтобы получить ' Python.h ' вам необходимо установить Python-dev, используя следующую команду —

$ sudo apt-get install python-dev 

Чтобы найти правильный путь к Python.h, выполните следующую команду —

$ python -config --cflags 

Это выведет что-то вроде этого —

Теперь замените путь в команде компиляции на этот для python2.7 или измените версию на python3.5 для Python 3.5 .

Теперь, наконец, мы должны связать сгенерированные объектные файлы вместе, чтобы создать общий объект, который подобен файлам DLL в Windows. Используйте следующую команду, это создаст общий объектный файл "_gfg.so"

$ gcc -shared gfg.o gfg_wrap.o -o _gfg.so 

Теперь мы готовы протестировать оболочку Python, импортировав ее. Убедитесь, что вы находитесь в каталоге с этим файлом оболочки.

> > > импортировать gfg > > > рез = факт (5) > > > разрешение 120 > > > res = my_mod (5,2) > > > рез 1 > > > gfg.cvar.myvar 3.4 

Здесь переменные C доступны как.

Компиляция и компоновка с использованием distutils

< / p>

Вместо того, чтобы вводить команды и выяснять, какие параметры компиляции необходимы для компиляции файлов, мы можем автоматизировать это с помощью distutils. Создайте, как показано ниже —


# Файл: setup.py


from distutils.core import setup, Extension

# имя модуля

имя = "gfg"


# версия модуля

version = "1.0"


# указать имя расширения и исходные файлы
# требуется для компиляции

ext_modules = Расширение (имя = ’_gfg’ , источники = [ "gfg.i" , " gfg.c " ] )


setup (name = имя,

версия = версия,

ext_modules = [ext_modules])

Теперь напишите следующие команды для компиляции и установки модуля —

$ python setup.py build_ext --inplace 

Это должно выглядеть так: что-то вроде этого на терминале —

Возможные альтернативы

Очевидно, что SWIG — не единственный способ создания оболочек, следующие альтернативы могут быть рассмотрены в зависимости от их требований —

В следующем В статье мы увидим, как оборачивать код C++ (OPP)

Ссылки

Эта статья предоставлена Атул Кумар < /сильный> . Если вы представляете Python.Engineering и хотели бы внести свой вклад, вы также можете написать статью, используя вклад.python.engineering или опубликовав статью. Внесите свой вклад @ python.engineering. См. мою статью, размещенную на домашней странице Python.Engineering, и помогите другим гикам.

Оставляйте комментарии, если вы обнаружите что-то не так или если вы хотите поделиться дополнительной информацией по обсуждаемой теме. выше.