2

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?

Axeman
  • 29,660
  • 2
  • 47
  • 102
Joel Berger
  • 20,180
  • 5
  • 49
  • 104

1 Answers1

6

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
ikegami
  • 367,544
  • 15
  • 269
  • 518
  • you know, I was just looking at the typemap as you posted this. I have a feeling that you are correct. And thanks for the info on `erro` as I don't come from a C background, I didn't know that. – Joel Berger Mar 21 '11 at 18:20
  • 1
    @Joel, [errno.h](http://linux.die.net/man/3/errno) provides portable constants (such as EACCES for permission denied) you can use to set `errno`. – ikegami Mar 21 '11 at 18:29