An alternative approach is to pack and unpack the array from the Perl side
Cool approach - it enables one to utilise the do_nothing() sub as it was presented in the original post.
For my own benefit, I turned it into an Inline::C demo:
use strict;
use warnings;
use Inline C => Config =>
BUILD_NOISY => 1,
USING => 'ParseRegExp',
;
use Inline C => <<'EOC';
double do_nothing(double x[], int sizeOfX) {
int index;
for(index=0; index<sizeOfX; index++) x[index] = 1;
return x[0];
}
void do_nothing_c(SV * sv) {
STRLEN len;
char * pv;
pv = SvPV_force(sv, len); /* SvPV() also seems ok */
do_nothing((double *)pv, len / sizeof(double));
}
EOC
my @in = (2.3, 3.4, 4.5, 5.6, 6.7);
my @ret = do_nothing(@in);
print "@in\n@ret\n";
sub do_nothing {
my $doubles = pack 'd*', @_;
do_nothing_c($doubles);
return unpack 'd*', $doubles;
}
__END__
Outputs:
2.3 3.4 4.5 5.6 6.7
1 1 1 1 1
I was initially a little concerned about there being both a Csub and a Perlsub named "do_nothing" but, of course, the Csub does not bind to Inline::C and the only sub named "do_nothing" that is visible from perl space is the Perlsub.
Conversely, the only sub named "do_nothing" that is visible from XS space is the Csub.
The return value of the do_nothing() Csub is not being captured anywhere in this demo. For the purposes of this demo it might just as well have been coded as:
void do_nothing(double x[], int sizeOfX) {
int index;
for(index=0; index<sizeOfX; index++) x[index] = 1;
}
Cheers, Rob |