Corion, you are the best. I think I've got it-
#!/usr/bin/perl
use strict;
use warnings;
use Inline 'C';
Inline->init;
my $buffer_size = 36; # (6x6)
print "Buffer size: $buffer_size\n";
my %template = (
"32,3" => 'f',
"32,1" => 'I',
"32,2" => 'i',
"8,1" => 'c',
"8,2" => 'C',
# ... add the other formats as you need
);
my $data;
print "char* data:\n";
$data = get_char_buffer();
printf "Raw data %s\n", $data;
print_buf( $data, 8, 1 ); # unsigned ints
print "\nfloat* data:\n";
print_buf( get_float_buffer(), 32, 3 ); # floating point
sub print_buf {
my ( $rawdata, $bps, $fmt ) = @_;
print "Ref count: " . get_ref_count( $rawdata ) . "\n";
my $t = $template{ "$bps,$fmt" }
or die "Couldn't find an unpack template for $bps BPS, format
+$fmt";
print "Template: $t\n";
my @samples = unpack( "${t}${buffer_size}", $rawdata );
print "Samples:\n@samples\n";
}
1;
__DATA__
__C__
#define BUF_SIZE 36
SV* get_char_buffer() {
void* buffer;
SV* sv_buf;
int i;
buffer = malloc(sizeof(char) * BUF_SIZE);
for (i = 65; i < 65 + BUF_SIZE; i++) { // printable chars
((char*)buffer)[i-65] = (char)i;
}
sv_buf = newSVpv(buffer,BUF_SIZE);
free(buffer);
return sv_buf;
}
SV* get_float_buffer() {
void* buffer;
SV* sv_buf;
int i;
buffer = malloc(sizeof(float) * BUF_SIZE);
for (i = 1; i <= BUF_SIZE; i++) {
((float*)buffer)[i-1] = (float)(i + 0.5);
}
sv_buf = newSVpv(buffer,32*BUF_SIZE);
free(buffer);
return sv_buf;
}
int get_ref_count(SV* buf) {
return (int)(SvREFCNT(buf));
}
|