I can't tell if this is a bug or what.
The following code works with Inline::C
but not Inline::CPP
#!/usr/bin/perl
use warnings;
use Inline C;
my @array = (1..10);
print findAvLen(\@array), "\n";
__END__
__C__
int findAvLen(AV* arrayIn) {
return av_len(arrayIn);
}
The above runs fine, but replace C
with CPP
, and I get the error Can't locate auto/main/findAvLen.al in @INC...
I can get other inline c++ code to work. It is possible, for instance, to pass a list of variables to inline code with an ellipsis as they do in this example, but I wonder why AV* isn't working! For instance, I will want to use a subroutine to converts perl arrays passed to C++ into vectors, e.g. void perl2vector(AV* ar, std::vector<T> &v) {...}
, rather than inserting code to perform such conversion into every C++ function I write that takes an array argument. How could I use that example's syntax to pass the perl array to such a converter?
This does seem to be a bug, but in the meantime, uesp has found a workaround:
int findAvLen(SV* arrRef) {
AV * arr = MUTABLE_AV(SvRV(arrRef));
return av_len(arr);
}
arr
is now equivalent to the arrayIn
desired in the example code above.
This appears to be be identical to this Perl bug which exists in 5.10.0 and should have been fixed in release 5.10.29. If you are running 5.10.0-28 try updating. If you aren't running these versions and still getting the error you can try doing what is mentioned in this forum post by changing the AV
to SV
.
SV
and see if that works for you. If it doesn't, or other trivial test C++ functions results in a similar error, then it is another issue - uesp 2012-04-04 19:10
int f(SV* arrayIn) { return 1; }
works, but I'm not sure how I can use SV to access an array (I have used Inline::C before, but never xs, so my experience is limited). Am reading perlguts.. - flies 2012-04-04 19:25
(AV*)SvRV(perlList)
converts a SV * (perlList
) to a AV *. SvRV is described here http://perldoc.perl.org/perlapi.html#SV-Manipulation-Function - flies 2012-04-04 19:47
AV * av = MUTABLE_AV(sv);
, which is a safer version of AV * av = (AV*)sv;
ikegami 2012-04-04 21:48
int findAvLen(SV* sv) { return av_len(MUTABLE_AV(sv)); }
doesn't seem to work, reports a junk positive integer. av_len(MUTABLE_AV(SvRV(sv)))
does work, and if you say it's safer than a plain typecast, I'll be glad to take your word for it. I can't find MUTABLE_AV
(nor MUTABLE_SV
) in the perlapi or perlguts docs, and the first page of google results doesn't help either - flies 2012-04-05 20:14
findAvLen(\@a)
. I understand that SvRV
dereferences \@a
, and then MUTABLE_AV
returns the appropriate type. Incidentally, is there a CONST_AV
? (I only need to read and not modify the argument. - flies 2012-04-05 20:21
MUTABLE_AV(SvRV(sv))
is indeed required - ikegami 2012-04-05 21:10
const AV*
, you mean? I don't think the typemap will recognize that if you use it as an argument. But you could cast the result of SvRV
to a const AV*
- ikegami 2012-04-06 11:22