M
Mirco Wahab
While trying to get along with some
"C to perl" interfacing, I stumbled
upon substr when using it to 'lvalue'
a packed scalar structure to a portion
of its string like
substr( $data, $offsett, $size ) = pack "ddd", $x, $y, $z;
which works fine (in the context I use it)
under Perl-587 (Inline::C 0.44) in Linux.
At a Win32-environment (Activeperl 587,
nmake, cl) this seem to fail sometimes.
Maybe I made a mistake that I'm not
aware of.
I'll include a short example where this
problem occurs. A C-function is called,
which allocates an SV* and writes
geometrical data (double) to it.
Back in perl, this data is unpacked
an printed (checked visually).
Then, this date is accessed by Perls
substr(), which works, as said, under
Linux but not under windows. The data
in $data gets messed up, as if perl
would cur out a portion of the string
and insert a new one of different size.
Thanks in advance,
Mirco
==>
#!/usr/lib/perl
use strict;
use warnings;
my $bsize = P3Dsize(); # sizeof(struct) from C
my $strct = "d3i"; # (atual) format of the above
my $vlen = 6; # number of elements to work with
my ($data, $x, $y, $z, $id, $blk); # some declarations
makesomevector_of($vlen, $data); # call into inline c
for my $idx (0 .. $vlen-1 ) {
# first: access structures and print (always fine!)
$blk = substr $data, $idx*$bsize, $bsize; # take out structure
($x, $y, $z, $id) = unpack $strct, $blk ; # unpack it
print " $x\t$y\t$z\t[$id]\n"; # print it (fine)
# second: access structures from Perl, !seems to fail in Win32!
substr( $data, $idx*$bsize, $bsize ) = pack $strct, $x+1, $y+1, $z+1, $id+1;
# third: access structures again and print (fails badly under W32/nmake/cl)
$blk = substr $data, $idx*$bsize, $bsize; # re-take structure
($x, $y, $z, $id) = unpack $strct, $blk; # unpack it
print "+$x\t$y\t$z\t[$id]+\n"; # print it (prints garbage!)
}
use Inline C => <<'END_OF_C_CODE';
typedef struct {
double x, y, z;
int id;
} P3D;
int P3Dsize() { return sizeof(P3D); }
int makesomevector_of(int Count, SV* perl_sv)
{
int id, blocksize = Count * P3Dsize();
P3D* pvec = (P3D*) malloc(blocksize);
if(pvec) {
for(id=0; id<Count; id++){
double val = id+1;
pvec[id].id = id;
pvec[id].x = val;
pvec[id].y = val*val;
pvec[id].z = val*val*val;
}
sv_setpvn( perl_sv, (char *)pvec, blocksize );
return 1;
}
return 0;
}
END_OF_C_CODE
"C to perl" interfacing, I stumbled
upon substr when using it to 'lvalue'
a packed scalar structure to a portion
of its string like
substr( $data, $offsett, $size ) = pack "ddd", $x, $y, $z;
which works fine (in the context I use it)
under Perl-587 (Inline::C 0.44) in Linux.
At a Win32-environment (Activeperl 587,
nmake, cl) this seem to fail sometimes.
Maybe I made a mistake that I'm not
aware of.
I'll include a short example where this
problem occurs. A C-function is called,
which allocates an SV* and writes
geometrical data (double) to it.
Back in perl, this data is unpacked
an printed (checked visually).
Then, this date is accessed by Perls
substr(), which works, as said, under
Linux but not under windows. The data
in $data gets messed up, as if perl
would cur out a portion of the string
and insert a new one of different size.
Thanks in advance,
Mirco
==>
#!/usr/lib/perl
use strict;
use warnings;
my $bsize = P3Dsize(); # sizeof(struct) from C
my $strct = "d3i"; # (atual) format of the above
my $vlen = 6; # number of elements to work with
my ($data, $x, $y, $z, $id, $blk); # some declarations
makesomevector_of($vlen, $data); # call into inline c
for my $idx (0 .. $vlen-1 ) {
# first: access structures and print (always fine!)
$blk = substr $data, $idx*$bsize, $bsize; # take out structure
($x, $y, $z, $id) = unpack $strct, $blk ; # unpack it
print " $x\t$y\t$z\t[$id]\n"; # print it (fine)
# second: access structures from Perl, !seems to fail in Win32!
substr( $data, $idx*$bsize, $bsize ) = pack $strct, $x+1, $y+1, $z+1, $id+1;
# third: access structures again and print (fails badly under W32/nmake/cl)
$blk = substr $data, $idx*$bsize, $bsize; # re-take structure
($x, $y, $z, $id) = unpack $strct, $blk; # unpack it
print "+$x\t$y\t$z\t[$id]+\n"; # print it (prints garbage!)
}
use Inline C => <<'END_OF_C_CODE';
typedef struct {
double x, y, z;
int id;
} P3D;
int P3Dsize() { return sizeof(P3D); }
int makesomevector_of(int Count, SV* perl_sv)
{
int id, blocksize = Count * P3Dsize();
P3D* pvec = (P3D*) malloc(blocksize);
if(pvec) {
for(id=0; id<Count; id++){
double val = id+1;
pvec[id].id = id;
pvec[id].x = val;
pvec[id].y = val*val;
pvec[id].z = val*val*val;
}
sv_setpvn( perl_sv, (char *)pvec, blocksize );
return 1;
}
return 0;
}
END_OF_C_CODE