gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-04 13:40:53 26 4
gpt4 key购买 nike

我试图通过Inline::C编写一个C函数,该函数将创建并返回对Perl的数组引用...下面是我的脚本和输出。我是否在分配数组并正确填充它?特别是,我创建了一个SV*的临时数组,并将它们传递给av_make,并返回使用newRV_noinc创建的引用。当我用Devel::Peek::Dump查看返回的数组ref时,引用计数似乎很好,它看起来与直接在perl中创建的相同数据结构相同。

我尚不了解什么是mortalization/sv_2mortal,或者在这里是否需要它。显然,Inline::C会在返回sv_2mortal的函数上自动调用SV*,这可能相关也可能无关。

#!/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 %d\n", len);
for (i = 0; i < len; i++) {
tmp_buffer[i] = newSViv(i);
}

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

printf("freeing tmp_buffer\n");
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,
1,
2,
3,
4,
5,
6,
7,
8,
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我写过,可能也有帮助。

关于perl - 我应该如何在Inline::C中创建并返回一个arrayref?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15349424/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com