I am building a module which connects to a camera, takes a picture, and reads the data into a piddle. All of this takes place in an Inline::C command. Using the procedure in the PDL documentation I can create a pdl *
and return it. However the camera could fail to take a picture in which case I would like to return 0
as per the usual covention my $pic_pdl = $Camera->TakePicture or die "Failed to take image"
. This seems to mean that I will need to use the Inline_Stack_Push
mechanism but I am not sure how to properly convert the pdl *
into an SV*
. Also I would like to, if possible, set $!
with the error code too. Can this be done in Inline?
The pdl*
is converted to an SV by code found in the typemap.
$ cat `perl -E'use PDL::Core::Dev; say PDL_TYPEMAP'`
TYPEMAP
pdl* T_PDL
pdl * T_PDL
Logical T_IV
float T_NV
INPUT
T_PDL
$var = PDL->SvPDLV($arg)
OUTPUT
T_PDL
PDL->SetSV_PDL($arg,$var);
If I read that right, you should be able to do something like:
SV* my_new {
pdl* p = NULL;
...
if (error) {
if (p)
free(p); /* I think */
return &PL_sv_undef;
} else {
SV* rv = newSV(0);
PDL->SetSV_PDL(rv, p);
return rv;
}
}
As for $!
, it's simply an interface to C's errno
. Simply set errno
.
$ perl -E'use Inline C => "void f(int i) { errno = i; }"; f($ARGV[0]); say 0+$!; say $!;' 2
2
No such file or directory
$ perl -E'use Inline C => "void f(int i) { errno = i; }"; f($ARGV[0]); say 0+$!; say $!;' 3
3
No such process
$ perl -E'use Inline C => "void f(int i) { errno = i; }"; f($ARGV[0]); say 0+$!; say $!;' 4
4
Interrupted system call