2016-06-04 7 views
2

언어에 대해 많은 바인딩을 만들 수있는 SWIG 파일이 있습니다. C 소스에는 고정 길이 목록 인 정수가있는 변수가 있습니다. Perl에서 액세스 할 때 항목이 없습니다. 단지 ARRAY임을 보여줍니다.SWIG typedef - Perl 배열

같은 문제는 파이썬에 있었다, 그러나 나는 꿀꺽 꿀꺽 타입 맵에 있음을 고정 수 :

#ifdef SWIGPYTHON 
%typemap(out) int [ANY] { 
    ... 

좋아, I'ld 펄 다시 그것을 할 싶어 -하지만 난 그렇게, 펄 전문가가 아니에요 필자는 Perl에서이 typemap을 수정할 수 있습니다.

#ifdef SWIGPERL 
%typemap(out) int [ANY] { 
    SV* sv = newSV(0); 
    AV* av = (AV *)sv_2mortal((SV *)newAV()); 
    int i = 0,len = 0; 
    printf("len: %d\n", $1_dim0); 
    len = $1_dim0; 

    for (i = 0; i < len ; i++) { 
     SV* perlval = newSV(0); 
     sv_setiv(perlval, (IV)$1[i]); 
     av_push(av, perlval); 
    } 
    SvSetSV($result, newRV_noinc((SV *)av)); 
} 
#endif 

펄 스크립트가 나에게 "LEN : 10"이 표시됩니다 : 이것은 내가 시도 할 것입니다 실행시,하지만 배열이 비어 :

$i=1; 
foreach(@m) { 
    print $i, "'", $_, "'\n"; 
    $i=$i+1; 
} 

결과는 다음과 같습니다

0 ''

무엇이 누락 되었습니까?

감사,

a.

는 편집 : 여기에 펄 스크립트입니다 : 이제

#!/usr/bin/perl 

use example1; 

# this function set up the built-in list in example1 module 
example1::get_att(7); 
my @m = $example1::m->{ilist}; 

# "m" is a C structure in C source, and it has an "int ilist[10];" member. 
# get_att(int n) will fill this list with "n" number 
# This will be accesable in binded lanugage (eg in Python) as like this: 
# print m.ilist -> [0, 3, 6, 9, 12, 15, 18, 0, 0, 0] 
$i = 0; 
foreach(@m) { 
    print $i, "'", $_, "'\n"; 
    $i=$i+1; 
} 

은,이 스크립트는이 결과를 생성합니다

len: 10 
0'' 

은 "렌 : 10"출력이 꿀꺽 꿀꺽 형식 정의에서 온 - "(printf와"를 참조하십시오 len : % d ... "줄 ...

+0

을 게시 - '수정'부분을 참조하십시오. 너는 무엇을 더 필요로 하는가? – airween

+0

[Crossposted] (http : //www.perlmonks.org /? node_id = 1164929). – choroba

+0

네, crossposted입니다 - 포럼/메일 링리스트의 목록이 있습니까, Stackoverflow에 달려 있으며 크로스 포스트로 표시됩니까? 나는 SO와 Perlmonks가 두 개의 다른 장소라고 생각했다. 어쨌든 미안 해요. – airween

답변

1

이전에 SWIG를 사용하지 않았지만 약간의 내용을 배우기 위해 상호 작용할 수 있다고 생각했습니다. 몇 시간 동안 documentation을 읽은 후에는 후우 문제를 해결할 수있는 무엇인가를 찾아야합니다.

%module example 

%typemap(out) int [ANY] { 
    AV* av = newAV(); 
    int i = 0,len = 0; 
    len = $1_dim0; 

    for (i = 0; i < len ; i++) { 
     SV* perlval = newSV(0); 
     sv_setiv(perlval, (IV)$1[i]); 
     av_push(av, perlval); 
    } 
    $result = newRV_noinc((SV*) av); 
    sv_2mortal($result); 
    argvi++; 
} 

%typemap(in) int [ANY] { 
    AV *tempav; 
    I32 len; 
    int i; 
    SV **tv; 
    if (!SvROK($input)) 
    croak("Argument $argnum is not a reference."); 
    if (SvTYPE(SvRV($input)) != SVt_PVAV) 
    croak("Argument $argnum is not an array."); 
    tempav = (AV*)SvRV($input); 
    len = av_len(tempav); 
    $1 = (int *) malloc((len+1)*sizeof(int)); 
    for (i = 0; i <= len; i++) { 
    tv = av_fetch(tempav, i, 0); 
    $1[i] = (int) SvIV(*tv); 
    } 
} 

%typemap(freearg) int * { 
    free($1); 
} 

%typemap(memberin) int [ANY] { 
    int i; 
    for (i = 0; i < $1_dim0; i++) { 
     $1[i] = $input[i]; 
    } 
} 

%inline %{ 

struct m { 
    int ilist[3]; 
}; 

%} 

그런 다음 우리가 example::m 패키지를 테스트 할 수있는 펄 스크립트를 작성해야합니다 : 먼저 우리는 인터페이스 파일 example.i 필요

use feature qw(say); 
use strict; 
use warnings; 

use example; 

my $m = example::m->new(); 
$m->{ilist} = [1, 2, 3]; 
my $list = $m->{ilist}; 

my $i = 0; 
for (@$list) { 
    say "$i: '$_'"; 
    $i=$i+1; 
} 

출력은 펄을 인터페이스 파일을 컴파일하고 실행 한 후 (지금 스크립트) :

0: '1' 
1: '2' 
2: '3' 

:

,
  • 내가 먼저 내가 사용하는 인터페이스 파일 example.i 컴파일 된 다음

    $ sudo apt-get install swig 
    
  • 를 사용하여 (우분투 16.04에) 꿀꺽 꿀꺽 3.0.8을 설치 : 나는를 완료

    $ swig -perl5 example.i 
    $ gcc -fpic -c -Dbool=char -D_GNU_SOURCE \ 
        -I/usr/lib/x86_64-linux-gnu/perl/5.22/CORE example_wrap.c 
    $ gcc -shared example.o example_wrap.o -o example.so 
    
+1

안녕하세요, 여러분의 많은 도움에 감사드립니다. 내 SWIG 파일, typemaps 및 Perl 파일을 제외한 모든 구성 요소가 올바른 것 같습니다. 나는 Perl 전문가가 아니다. (나는 Perl을 모른다.) Perl 스크립트는 여기에있다 : http://www.perlmonks.org/?node_id=1164929. 다시 한 번 감사드립니다! – airween