Perl, C, XS - unpack float array

242 views Asked by At

I have Perl Code and C Code and I am calling C functions in my Perl Code. I have passed a float array from Perl to C by packing it (like this http://www.perlmonks.org/?node_id=39697) and it works nicely!

my $p_angle = pack("f*", @angle);

But now I am trying to return that array from my C function to Perl and I want to be able to do stuff with it, e.g read values, print...

I have tried to unpack it with

my @array = unpack("f*", $entropy);

but that does not work at all, I always see the same not reasonable values when I print the @array.

So I guess I am doing it wrong, does anybody know how to unpack the array properly?

1

There are 1 answers

0
ikegami On
use strict;
use warnings;
use feature qw( say );

use Inline C => <<'__EOS__';

#include <stdio.h>

SV* test(SV* sv) {
   float* array;
   size_t num_eles;
   {
      STRLEN len;
      char* s = SvPVbyte(sv, len);
      num_eles = len/sizeof(float);

      /* We can't just cast s because we could */
      /* run afoul of alignment restrictions. */
      array = malloc(len);
      memcpy(array, s, len);
   }

   {
      size_t i;
      for (i=0; i<num_eles; ++i) {
         printf("%zu %.6f\n", i, (double)(array[i]));
      }
   }

   {
      SV* return_sv = newSVpv((char*)array, num_eles*sizeof(float));
      free(array);
      return return_sv;  /* The typemap will mortalize. */
   }
}

__EOS__

my @a = (1.2, 1.3, 1.4);
say sprintf "%u %.6f", $_, $a[$_] for 0..$#a;
my $a = pack('f*', @a);
my $b = test($a);
my @b = unpack('f*', $b);
say sprintf "%u %.6f", $_, $b[$_] for 0..$#b;