Empacotamento C/C++ para Python usando SWIG — Conjunto 1

| | | | | | | | | | |

Não há dúvida de que Numpy, executa uma enorme quantidade de tarefas ? Na verdade, bibliotecas como Numpy não são escritas inteiramente em Python, algumas partes da biblioteca são escritas em C, o que proporciona melhor desempenho. Depois de escrever o código C, nós os envolvemos no código Python, que atua como uma interface para esses códigos C. Podemos então chamar funções C usando a sintaxe Python, onde o processamento real é feito em C nos bastidores e o resultado é retornado como um objeto Python. Neste artigo, veremos como criar um wrapper Python para nosso programa C em sistemas Linux usando o software SWIG .

O que é SWIG >

Em poucas palavras, SWIG — é um compilador que aceita declarações C/C++ e as envolve para acessar essas declarações de outras linguagens ‚Äã‚Äãcomo Python, Tcl, Ruby, etc.
Geralmente isso não requer nenhuma alteração no código existente e cria uma interface em um minuto.

Razões para criar um wrapper

Em muitos casos, precisamos de wrappers, os seguintes são —

  • Construindo uma interface interpretada para programas C existentes.
  • Construir módulos C de alto desempenho para linguagens de script ‚Äã‚Äã
  • Testar grandes programas C é muito difícil, então escrevemos wrappers em algumas linguagens de script ‚Äã‚Äãcomo Python, onde é muito fácil escrever testes. etc

Instalando o SWIG

Para baixar o SWIG diretamente do repositório apt, digite os seguintes comandos —

sudo apt-get update sudo apt-get install swig 

Escrevendo um wrapper usando SWIG

Vamos ver este pedaço de código em C com duas funções e uma variável global —


/ * file: gfg.c * /


# inclui "stdio.h >
# inclui "math.h >


// nosso arquivo de cabeçalho
# include "gfg.h"
# define ll long long


double minhavar = 3.4;


// calcula fatorial

ll int fato (ll int n)

{

if (n "= 1)

return 1;

else

return (n * fato (n-1));

}


// encontre o mod

int my_mod ( int n, int m )

{

return (n% m);

}

Aqui está nosso arquivo de cabeçalho — ;


longo longo int fato ( long long int n);

int my_mod ( int n, int m);

Primeiro temos que criar o arquivo de interface SWIG . Este arquivo contém protótipos de funções ANSI C e declarações de variáveis. Aqui —

  • A diretiva % module especifica o nome do módulo que usaremos em Python.
  • % {. . % } fornece um local para inserir código adicional, como arquivos de cabeçalho C ou declarações C adicionais, no código wrapper gerado.
  • A diretiva % include nos permite incluir arquivos adicionais, como arquivos de cabeçalho.

/ * arquivo: gfg.i * /


/ * nome do módulo usado * /
% module gfg
% {

/ * Tudo neste arquivo é copiado para o

arquivo encapsulador. Inclua o arquivo de cabeçalho C necessário

compilar a interface * /

# include "gfg.h"

/ * declaração de variável * /

double myvar;

%}


/ * lista explicitamente funções e variáveis para interação * /

double myvar;

longo longo int fato ( longo longo int n1);

int my_mod ( int m, int n);


/ * ou se quisermos vincular todas as funções, podemos apenas

inclua um arquivo de cabeçalho como este -

% include & quot; gfg.h & quot;

* /

Agora vamos criar o código wrapper usando um comando como

$ swig -python gfg.i 

Este comando gera um código wrapper chamado "gfg_wrap.c" . Esses arquivos contêm uma versão inchada de nossa fonte C com código de tratamento de erros diferente, etc. Gerou outro arquivo "gfg.py", que é o módulo que estamos importando para nosso script python.


Depois disso, temos que gerar código independente de posição para ser usado na biblioteca compartilhada compilando "gfg_wrap.c" e "gfg .c" com o seguinte comando:

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

Substituir python2 .7 com sua versão do Python. Isso criará dois arquivos de objeto
"Gfg_wrap.o‚" e "gfg.o‚" . No comando acima —

  • gerar código independente de posição (PIC) adequado para uso na biblioteca compartilhada, se houver suporte para a máquina de destino. Este código acessa todos os endereços permanentes por meio da Global Offset Table (GOT)

Observação: se você receber uma mensagem de erro como as seguintes causas possíveis —

  • Você pode não ter o ' Python.h ' ou
  • Você está digitando o local errado para o ' Python.h ' para o compilador

Para obter ' Python.h ' você precisa instalar o Python-dev, usando o seguinte comando —

$ sudo apt-get install python-dev 

Para encontrar o caminho correto para Python.h, execute o seguinte comando —

$ python -config --cflags 

Isto produzirá algo assim —

Agora substitua o caminho no comando de compilação por este para python2.7 ou altere a versão para python3.5 para Python 3.5 .

Agora, finalmente, temos que vincular os arquivos de objetos gerados para criar um objeto compartilhado, que é semelhante aos arquivos DLL no Windows. Use o seguinte comando, isso irá gerar um arquivo de objeto compartilhado "_gfg.so"

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

Agora estamos prontos para testar o shell Python importando-o. Certifique-se de estar no diretório com este arquivo shell.

> > > importar gfg > > > res = fato (5) > > > res 120 > > > res = meu_mod (5,2) > > > res 1 > > > gfg.cvar.myvar 3.4 

Aqui as variáveis C estão disponíveis como.

Compilando e vinculando usando distutils

< / p>

Em vez de digitar comandos e descobrir quais opções de compilação são necessárias para compilar arquivos, podemos automatizar isso com distutils. Crie conforme mostrado abaixo —


# Arquivo: setup.py


from distutils.core import configuração, Extensão

# nome do módulo

name = "gfg"


# versão do módulo

versão = "1.0"


# especifique o nome da extensão e os arquivos de origem
# necessário para compilação

ext_modules = Extensão (name = ’_gfg’ , fontes = [ " gfg.i " , " gfg.c " ] )


setup (name = nome,

versão = versão,

ext_modules = [ext_modules])

Agora escreva os seguintes comandos para compilar e instalar o módulo —

$ python setup.py build_ext --inplace 

Isso deve se parecer com do algo assim no terminal —

Alternativas possíveis

Obviamente, SWIG — não é a única maneira de criar wrappers, as alternativas a seguir podem ser consideradas com base em seus requisitos —

No próximo artigo veremos como encapsular código C++ (OPP)

Links

Este artigo é cortesia de Atul Kumar . Se você é Python.Engineering e gostaria de contribuir, você também pode escrever um artigo usando contribute.python.engineering ou postando um artigo contribua @ python.engineering. Veja meu artigo que aparece na página inicial do Python.Engineering e ajude outros geeks.

Por favor, poste comentários se encontrar algo errado ou se quiser compartilhar mais informações sobre o tópico discutido acima.

Shop

Learn programming in R: courses

$

Best Python online courses for 2022

$

Best laptop for Fortnite

$

Best laptop for Excel

$

Best laptop for Solidworks

$

Best laptop for Roblox

$

Best computer for crypto mining

$

Best laptop for Sims 4

$

Latest questions

NUMPYNUMPY

psycopg2: insert multiple rows with one query

12 answers

NUMPYNUMPY

How to convert Nonetype to int or string?

12 answers

NUMPYNUMPY

How to specify multiple return types using type-hints

12 answers

NUMPYNUMPY

Javascript Error: IPython is not defined in JupyterLab

12 answers


Wiki

Python OpenCV | cv2.putText () method

numpy.arctan2 () in Python

Python | os.path.realpath () method

Python OpenCV | cv2.circle () method

Python OpenCV cv2.cvtColor () method

Python - Move item to the end of the list

time.perf_counter () function in Python

Check if one list is a subset of another in Python

Python os.path.join () method