加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

perl – 我应该如何在Inline :: C中创建并返回一个arrayref?

发布时间:2020-12-15 22:00:52 所属栏目:大数据 来源:网络整理
导读:我试图通过Inline :: C编写一个C函数,它将创建并返回一个对Perl的数组引用…下面是我的脚本和输出.我是否正在分配阵列并正确填充它?特别是,我创建一个临时的SV *数组并将它们传递给av_make,并返回用newRV_noinc创建的引用.当我使用Devel :: Peek :: Dump查
我试图通过Inline :: C编写一个C函数,它将创建并返回一个对Perl的数组引用…下面是我的脚本和输出.我是否正在分配阵列并正确填充它?特别是,我创建一个临时的SV *数组并将它们传递给av_make,并返回用newRV_noinc创建的引用.当我使用Devel :: Peek :: Dump查看返回的数组ref时,引用计数似乎很好,它看起来与直接在perl中创建的相同数据结构相同.

我还不知道什么是mortalization / sv_2mortal,或者我是否需要它.显然,Inline :: C会在返回SV *的函数上自动调用sv_2mortal,这可能与也可能不相关.

#!/usr/bin/env perl
use strict;
use warnings FATAL => "all";
use 5.010_000;
use Data::Dumper;
use autodie;

use Inline ('C');
use Devel::Peek;

my $from_perl = [0 .. 9];
my $from_c = inline_array_maker(10); #same as above but in C

say Dumper $from_perl;
Dump($from_perl);

say Dumper $from_c;
Dump($from_c);


__END__
__C__
SV* (int len){
    int i;
    SV ** tmp_buffer;
    AV * arr;

    tmp_buffer  = malloc(sizeof(SV*) * len);

    printf("allocating tmp_buffer of size %dn",len);
    for (i = 0; i < len; i++) {
        tmp_buffer[i] = newSViv(i);
    }

    // is av_make the most efficient way of doing this?  
    printf("av_maken");
    arr = av_make(len,tmp_buffer);

    printf("freeing tmp_buffern");
    for (i = 0; i < len; i++) {
        sv_free(tmp_buffer[i]);
    }
    free(tmp_buffer);

    return newRV_noinc(arr);
}

我得到以下输出.

allocating tmp_buffer of size 10
av_make
freeing tmp_buffer
$VAR1 = [
        0,1,2,3,4,5,6,7,8,9
        ];

SV = IV(0x20c7520) at 0x20c7530
REFCNT = 1
FLAGS = (PADMY,ROK)
RV = 0x21c0fa8
SV = PVAV(0x25c7ec8) at 0x21c0fa8
    REFCNT = 1
    FLAGS = ()
    ARRAY = 0x25a0e80
    FILL = 9
    MAX = 9
    ARYLEN = 0x0
    FLAGS = (REAL)
    Elt No. 0
    SV = IV(0x20b2dd8) at 0x20b2de8
    REFCNT = 1
    FLAGS = (IOK,pIOK)
    IV = 0
    Elt No. 1
    SV = IV(0x20b2fb8) at 0x20b2fc8
    REFCNT = 1
    FLAGS = (IOK,pIOK)
    IV = 1
    Elt No. 2
    SV = IV(0x20c69f8) at 0x20c6a08
    REFCNT = 1
    FLAGS = (IOK,pIOK)
    IV = 2
    Elt No. 3
    SV = IV(0x20c6a10) at 0x20c6a20
    REFCNT = 1
    FLAGS = (IOK,pIOK)
    IV = 3
$VAR1 = [
        0,9
        ];

SV = IV(0x20d25c8) at 0x20d25d8
REFCNT = 1
FLAGS = (PADMY,ROK)
RV = 0x25ac6b8
SV = PVAV(0x25c7ea0) at 0x25ac6b8
    REFCNT = 1
    FLAGS = ()
    ARRAY = 0x25b9140
    FILL = 9
    MAX = 9
    ARYLEN = 0x0
    FLAGS = (REAL)
    Elt No. 0
    SV = IV(0x25aca80) at 0x25aca90
    REFCNT = 1
    FLAGS = (IOK,pIOK)
    IV = 0
    Elt No. 1
    SV = IV(0x25ac750) at 0x25ac760
    REFCNT = 1
    FLAGS = (IOK,pIOK)
    IV = 1
    Elt No. 2
    SV = IV(0x25ac5e8) at 0x25ac5f8
    REFCNT = 1
    FLAGS = (IOK,pIOK)
    IV = 2
    Elt No. 3
    SV = IV(0x25ac930) at 0x25ac940
    REFCNT = 1
    FLAGS = (IOK,pIOK)
    IV = 3

解决方法

你读过 perldoc perlguts吗?它应该可以帮到你的大部分路. Inline :: C也可以处理AV *返回值.我可能会这样做:
#!/usr/bin/env perl

use strict;
use warnings;

use Inline C => <<'END';
  AV* make_arrayref (int size) {
    int i;
    AV* ret = newAV();
    sv_2mortal((SV*)ret);
    for(i=0; i<size; i++) {
      av_push(ret,newSViv(i) );
    }
    return ret;
  }
END

my $arrayref = make_arrayref(10);
print "$_n" for @$arrayref;

Here is some code我写的也可能有所帮助.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读