nereida:~/Lperl-5.9.4> sed -ne '46,64p' sv.h | cat -n
1 typedef enum {
2 SVt_NULL, /* 0 Usado para undef */
3 SVt_IV, /* 1 Entero */
4 SVt_NV, /* 2 Flotante */
5 SVt_RV, /* 3 Referencia */
6 SVt_PV, /* 4 Cadena */
7 SVt_PVIV, /* 5 Cadena o Entero */
8 SVt_PVNV, /* 6 Cadena o Flotante */
9 SVt_PVMG, /* 7 Objeto o escalar mágico */
10 SVt_PVBM, /* 8 Como SVt_PVMG: si es cadena usa Boyer-Moore para las búsquedas */
11 SVt_PVGV, /* 9 Typeglob */
12 SVt_PVLV, /* 10 Varios tipos con conducta Lvalue */
13 SVt_PVAV, /* 11 Array */
14 SVt_PVHV, /* 12 Hash */
15 SVt_PVCV, /* 13 Código */
16 SVt_PVFM, /* 14 Formato */
17 SVt_PVIO, /* 15 Manejador de ficheros */
18 SVt_LAST /* keep last in enum. used to size arrays */
19 } svtype;
En la jerga, estos tipos son conocidos como IV, NV, PV, etc.
Nótese que arrays y hashes son formas de SVs.
Existe toda una familia de funciones
con nombres SvIV, SvNV, SvPV, etc
para leer un escalar (SV) como entero, flotante, cadena, etc.
El siguiente código muestra el uso de algunas de estas funciones de
acceso:
lhp@nereida:~/Lperl/src/XSUB/inline$ cat -n dump_values.pl
1 #!/usr/local/bin/perl -w
2 use strict;
3 use Inline C => <<'EOC';
4 void dump_scalar(SV * sv) {
5
6 printf("Flotante: %f\n", SvNV(sv));
7 printf("Entero: %i\n", SvIV(sv));
8 printf("Cadena: %s\n", SvPV_nolen(sv));
9 printf("Longitud de la cadena: %i\n", SvCUR(sv));
10 printf("Longitud del espacio asignado para la cadena: %i\n", SvLEN(sv));
11 }
12 EOC
13
14 my $a = "123.53";
15 dump_scalar($a)
El caso de las cadenas es mas complejo: se puede acceder a la longitud
de la cadena mediante la macro SvCUR y a la longitud de su buffer
mediante la macro SvLEN. Al ejecutar el programa anterior obtenemos la
salida:
lhp@nereida:~/Lperl/src/XSUB/inline$ dump_values.pl Flotante: 123.530000 Entero: 123 Cadena: 123.53 Longitud de la cadena: 6 Longitud del espacio asignado para la cadena: 8
Existe una familia de funciones sv_setiv, sv_setnv, sv_setpv, etc. que permiten la modificación del escalar. Por ejemplo:
lhp@nereida:~/projects/perl/src/XSUB/inline$ cat -n set_values.pl
1 #!/usr/local/bin/perl -w
2 use strict;
3 use Inline C => <<'EOC';
4 void set_string(SV * sv) {
5 char h[256];
6 printf("Input: ");
7 scanf("%s", &h);
8 sv_setpv(sv, h);
9 }
10 EOC
11
12 my $a;
13 set_string($a);
14 print "$a\n";
Casiano Rodríguez León