Perl Inline :: C возвращает pdl или 0 при ошибке - PullRequest
2 голосов
/ 21 марта 2011

Я строю модуль, который подключается к камере, делает снимок и считывает данные в ячейку.Все это происходит в команде Inline :: C.Используя процедуру из PDL документации , я могу создать pdl * и вернуть его.Однако камера может не сделать снимок, и в этом случае я хотел бы вернуть 0 в соответствии с обычным соглашением my $pic_pdl = $Camera->TakePicture or die "Failed to take image".Кажется, это означает, что мне нужно будет использовать механизм Inline_Stack_Push, но я не уверен, как правильно преобразовать pdl * в SV*.Также я хотел бы, если возможно, установить $! с кодом ошибки.Можно ли это сделать в Inline?

1 Ответ

6 голосов
/ 21 марта 2011

pdl* преобразуется в SV по коду, найденному в карте типов.

$ 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);

Если я правильно понял, вы сможете сделать что-то вроде:

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;
    }
}

Что касается $!, это просто интерфейс к C errno.Просто установите 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
...