Otavio Fernandes

Introdução ao Inline::C
Publicado em 01/12/2006

r3 - 01 Dec 2006 - OtavioFernandes

Introdução ao Inline::C

Inclua códigos-fonte de outras linguagens dentro do seu script Perl !

Introdução:

O Inline é um módulo que permite que você acrescente código de outras linguagens de programação diretamente no seu script Perl, salvando-o de ter que escrever dois programas e fazê-los "conversar", gastando muito mais tempo do que se você pudesse simplesmente misturar as linguagens ... mas com a flexibilidade do Perl e a ajuda do Inline você pode ! Nas linhas abaixo estarei demonstrando de forma descontraída e objetiva como isso é possível.

Fazendo a Instalação:

Antes de fazermos uso do Inline, temos que fazer a instalação, para isso separei duas formas de realizá-la; uma via CPAN, a qual eu recomendo, pois é muito mais fácil centralizar os pacotes do Perl em uma única ferramenta, e também podemos ter sempre a versão mais nova de cada módulo, o que nem sempre acontece com os pacotes pré-compilados; e outra via apt-get:

CPAN:

Com a mesma simplicidade dos códigos em Perl, utilizamos a CPAN: Neste primeiro passo, chamamos o prompt para execução de comandos:

 perl -MCPAN -e shell

Logo em seguida devemos requisitar a instalação do módulo Inline:

 install Inline

Pronto. Observe os retornos e se necessário trate os erros que aparecerão no meio do caminho. Não extenderei mais esta parte pois este não é o nosso foco.

Debian:

No Debian, com a utilização do apt-get, as coisas ficam tão fáceis quanto na CPAN, basta executar o seguinte comando (como root, ou com permissões de super-usuário):

 # apt-get update
 # apt-get install libc-scan-perl libinline-octave-perl libinline-perl libtest-inline-perl

E esperar o retorno do comando, aqui nos meus testes eu não tive nenhum problema com os dois tipos de instalação.

Exemplos Práticos:

Em um determinado momento da nossa vida de programadores, seja profissionalmente ou apenas por diversão, faz-se necessário a execução de algum(s) método(s) de uma biblioteca natural de outra linguagem, o que para alguns casos, é aparentemente inviável, mas com a flexibilidade do Perl, e as inovações dos módulos presente na CPAN isso é mais do que possível, é fácil e muito prático. Nos exemplos abaixo, estaremos chamando métodos da nossa "libteste", a qual está presente no diretório "/usr/lib" e tem seus headers no diretório "/usr/include", o teste.h, para dificultar as coisas, quando instânciamos a libteste, precisamos ter declarado dentro do nosso fonte uma estrutura (struct), servindo para troca de dados, o nome dela é treetst (bem sugestivo :-P):

Utilizando o Inline C, podemos fazer uso das funções de duas formas distintas:

1) Escrevendo um trecho de código C que faça a chamada da função, e retorne seu conteúdo para o nosso script:

 01| #!/usr/bin/perl
 02|
 03| use scrict;
 04| use warnings;
 05|
 06| # fazendo a chamada direta da função escrita no código abaixo
 07| my $retr = WrapFTest();
 08|
 09| # imprimindo na stdout o retorno da função WrapFTest
 10| print $retr, "\n";
 11|
 12| # declarando a nossa libteste como parâmetro para compilação
 13| use Inline C => Config => ENABLE => AUTOWRAP => LIBS => '-lteste';
 14| # da próxima linha até a string "END_OF_C_CODE" tudo é código C
 15| use Inline C => << 'END_OF_C_CODE';
 16|
 17| #include 
 18|
 19| struct treetst *p1, *p1;
 20|
 21| int WrapFTest () { return Teste(); }
 22|
 23| END_OF_C_CODE

Segue o comentário das linhas mais importantes deste código, na mesma organização que o interpretador e o Inline o fazem:

 [16-22]

Junção deste código ao trecho pré existente de código C, preparado para o enxerto de novas linhas. Atente que o nosso fonte tem todos os requisitos para compilar a executar a libteste, ou seja, a presença do "include" de seu header "teste.h" e também apresenta da estrutura "treetst", necessária para troca de dados (não tratados aqui);

 [13]

Configurando como será a compilação do código C, com o uso da "-lteste" junto com o gcc, esta linha que permite ao compilador saber qual biblioteca estamos procurando. Para maiores detalhes, execute o comando "# ldconfig -v" e faça uma breve análise dos resultados retornados;

 [07]

Fazendo a execução da função "WrapFTest()", a qual tem o papel de intermediar a execução da função que nos interessa, a "Teste()". Fazemos uso desta função porque não temos acesso direto à libteste, apenas ao pseudo-código que geramos no bloco de linhas 16 a 22;

 [10]

Imprimindo o retorno da função "Teste()". Lembrando que o retorno, ou parâmetros, ou até estruturas de dados, podem trocados entre o script e o código C (outras linguagens também).

Pronto, executamos uma chamada na libteste através do nosso pequeno, porém eficiente, código ANSI C, veremos no próximo exemplo como fazer isso de forma direta.

2) Podemos instânciar as funções diretamente da biblioteca e fazer uso no nosso script:

 01| #!/usr/bin/perl -w
 02|
 03| use warnings;
 04| use strict;
 05|
 06| use Inline C => Config => ENABLE => AUTOWRAP => LIBS => "-lteste";
 07| use Inline C => q{ struct treetst *p1, *p2; };
 08| use Inline C => q{ int Teste(); };
 09|
 10| my $retr = Teste();
 11|
 12| print $retr, "\n";

Neste exemplo estamos acessando a libteste diretamente do nosso script em Perl, sem a ajuda de código para enxerto, apenas com o protótipo das funções (vide o arquivo header para maiores detalhes). Segue o comentário e explicação das linhas mais influentes do nosso script:

 [07]

Declarando a estrutura que vamos utilizar para trocar os dados com a libteste, assim como fariamos em um código C comum (vide Caso 1);

 [08]

Protótipo da função "Teste()", presente no header "/usr/include/teste.h";

 [10]

Eureca. Estamos acessando a função "Teste()" diretamente do nosso script :-);

 [12]

Imprimindo na saída padrão o retorno da função "Teste()";

Sobre o Autor:

Otávio Fernandes, exercendo atualmente o cargo Programador Sênior e Gerente de Projetos, tem larga experiência em appliances para servidores de E-Mail e Anti-SPAM, fluência em linguagens como ANSI C e C++, porem um aprendiz em Perl. Contato otaviof at gmail dot com.

Bibliografia:

http://search.cpan.org/~ingy/Inline-0.44/C/C.pod

http://search.cpan.org/~ingy/Inline-0.44/Inline.pod

http://search.cpan.org/~ingy/Inline-0.44/C/C-Cookbook.pod

AUTHOR

Otavio Fernandes

blog comments powered by Disqus