2014-04-06 17 views
7

Programowałem C przez jakiś czas. Teraz muszę napisać program w języku C, który może wywoływać perl. Powinna mieć taką samą składnię jak następująca funkcja atrapy perl: Weź dwa wejścia, oba są łańcuchami (mogą zawierać znaki binarne, nawet "\ x00"), wypisz nowy ciąg.jak napisać funkcję C i móc ją wywołać z perl

Oczywiście algorytm funkcji będzie bardziej skomplikowane, dlatego muszę to zrobić w C.

sub dummy { 
    my ($a, $b) = @_; 
    return $a . $b; 
} 

mam krótko spojrzał na SWIG do wdrożenia, ale biorąc wejścia/ouput inne niż liczba całkowita nie jest łatwa, mam nadzieję, że ktoś da konkretny przykład.

Z góry dziękuję.

UPDATE: Dostałem świetny przykład od Rob (autor modułu Inline :: C w cpan), dzięki!

############################## 
use warnings; 
use strict; 
use Devel::Peek; 

use Inline C => Config => 
BUILD_NOISY => 1, 
; 

use Inline C => <<'EOC'; 

SV * foo(SV * in) { 
SV * ret; 

STRLEN len; 
char *tmp = SvPV(in, len); 
ret = newSVpv(tmp, len); 
sv_catpvn(ret, tmp, len); 
return ret; 

} 

EOC 

my $in = 'hello' . "\x00" . 'world'; 
my $ret = foo($in); 


Dump($in); 
print "\n"; 
Dump ($ret); 

############################## 

Odpowiedz

11

Perl ma język kleju o nazwie XS do tego rodzaju rzeczy. Wie o odwzorowaniach między typami danych Perla i typami C. Na przykład, funkcja C

char *dummy(char *a, int len_a, char *b, int len_b); 

może być owinięty przez kod XS

MODULE = Foo PACKAGE = Foo 

char * 
dummy(char *a, int length(a), char *b, int length(b)); 

Plik Foo.xs zostaną skompilowane, gdy zainstalowany jest moduł, wszystkie odpowiednie łańcuchy build tool mieć wsparcie XS.

Argument kod konwersji zostanie wygenerowany automatycznie, tak że funkcja może być wywołana w Perlu jako Foo::dummy("foo", "bar"), gdy kod XS został załadowany z Perl:

package Foo; 
use parent 'DynaLoader'; 
Foo->bootstrap; 

Jest XS tutorial w dokumentacji Perl, i dokumentacja referencyjna w perlxs.

XS to dobry wybór dla modułów, ale jest niezręczny dla jednorazowych skryptów. Moduł Inline::C umożliwia osadzenie kodu C z klejem bezpośrednio w skrypcie Perla i zajmie się automatyczną kompilacją za każdym razem, gdy zmieni się kod C. Jednak dzięki temu podejściu można automatycznie wygenerować mniej kodu.

+0

Dzięki za szybką odpowiedź i łącze. Wydaje się, że Inline :: C zmniejszyło ból używania perlxów u kogoś, kto nie zna perl jelli. Jest książka kucharska z licznymi przykładami użycia Inline :: C: https://metacpan.org/pod/Inline::C-Cookbook. – packetie

Powiązane problemy