SWIG typedef - 将数组返回到Perl

时间:2017-02-16 15:17:53

标签: c arrays perl int swig

我有一个SWIG文件从.C文件中获取输出int数组并将其传递给Perl,以便我可以在Perl中打印数组值。 C源代码中有一个Function,它将返回一个int数组。当我试图在Perl中打印这些值时,它不会打印数组值。

我有这个名为perl.i的swig文件 这是我尝试的:

#ifdef SWIGPERL
%module aticara
%{
#include "include.h"
extern int myfunction();
%}
%typemap(out) int [ANY] {
}
int myfunction();
#endif

我不知道在typemap中写什么。 perl脚本在运行时调用了test.pl,但是数组为空: 这是我的test.pl

#!/usr/bin/perl
use aticara;
use feature qw(say);

my $arr = aticara::myfunction();
my $list = $arr;

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

打印空白。 我不缺少我想念的地方和地点。但我能说的一件事是它来自我的swig文件。 而且我正在共享我的C文件,它将返回一个数组列表。

这是我的c档案:

int myfunction()
{
    int a[5];
    a[0] = 45;
    a[1] = 4;
    a[2] = 8;
    a[3] = 9;
    a[4] = 1;
    return *a;
}

Perl的预期输出是:

0: 45 
1: 4 
2: 8 
3: 9 
4: 1

但我无法获得此输出。我不会那么开心。 如果有人帮我出去,那就太好了。 在此先感谢。

1 个答案:

答案 0 :(得分:0)

您应该返回一个指向int数组的指针,而不是本地数组a的第一个元素的内容。而是使用malloc()创建数组,并使用SWIG ret类型映射来释放它。然后还创建一个out类型映射,将返回的数组转换为Perl数组。以下是如何完成的示例:

<强> example.i

%module example
%{
#include "example.h"
%}
%typemap(out) int * {
    AV *myav;
    SV **svs;
    int len = 0;
    /* Figure out how many elements we have */
    while ($1[len])
        len++;
    svs = (SV **) malloc(len*sizeof(SV *));
    int i;
    for (i = 0; i < len ; i++) 
        svs[i] = newSViv($1[i]);
    myav = av_make(len, svs);
    free(svs);
    $result = newRV_noinc((SV*)myav);
    sv_2mortal($result);
    argvi++;
}
%typemap(ret) int * %{
  free($1);
%}
%include "example.h"

<强> example.h文件

#include <stdlib.h>
extern int *myfunction();

<强> example.c

#include "example.h"

int *myfunction()
{
    int *a = (int *) malloc( 5*sizeof(int) );
    a[0] = 45;
    a[1] = 4;
    a[2] = 8;
    a[3] = 9;
    a[4] = 1;
    return a;
}

<强> test.pl

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

use example;

my $arr = example::myfunction();

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

编译(Ubuntu 16.10 with perlbrew):

swig -perl5 example.i
perl_dir=~/perlbrew/perls/perl-5.24.1/lib/5.24.1/x86_64-linux/CORE 
gcc -fpic -c example.c
gcc -fpic -c -Dbool=char -D_GNU_SOURCE -I"$perl_dir" example_wrap.c
gcc -shared example.o example_wrap.o -o example.so

运行

$ perl test.pl
0: '45'
1: '4'
2: '8'
3: '9'
4: '1'