rectangular * viene dada por
la entrada T_PTROBJ del fichero typemap de la instalación. 
La entrada y la salida para esta interfaz son:
lhp@nereida:~/Lperl/src/XSUB/h2xsexample/Coord$ cat -n /usr/share/perl/5.8/ExtUtils/typemap
     1  # basic C types
     2  int                     T_IV
....................................
    50  FileHandle              T_PTROBJ
....................................
    56  #############################################################################
    57  INPUT
    58  T_SV
    59          $var = $arg
....................................
   137  T_PTROBJ
   138          if (sv_derived_from($arg, \"${ntype}\")) {
   139              IV tmp = SvIV((SV*)SvRV($arg));
   140              $var = INT2PTR($type,tmp);
   141          }
   142          else
   143              Perl_croak(aTHX_ \"$var is not of type ${ntype}\")
....................................
   193  #############################################################################
   194  OUTPUT
   195  T_SV
   196          $arg = $var;
   197  T_SVREF
   198          $arg = newRV((SV*)$var);
....................................
   252  T_PTROBJ
   253          sv_setref_pv($arg, \"${ntype}\", (void*)$var);
Tenemos un método por cada campo.
El método  x recibe la referencia THIS
a la estructura rectangular
y -opcionalmente- el valor __value
a almacenar en la componente.
68 MODULE = Coord PACKAGE = rectangularPtr 69 70 double 71 x(THIS, __value = NO_INIT) 72 rectangular * THIS 73 double __value 74 PROTOTYPE: $;$ 75 CODE: 76 if (items > 1) 77 THIS->x = __value; 78 RETVAL = THIS->x; 79 OUTPUT: 80 RETVAL
Es posible especificar valores por defecto para los argumentos de una XSUB. 
Esto se hace especificandolos mediante asignaciones en la parte de 
la lista de parámetros. El valor por defecto puede ser un número, una cadena o 
-como es el caso del ejemplo - la cadena especial  NO_INIT .
Sólo es posible especificar valores por defecto para los parámetros
mas a la derecha.
Obervese que la semántica de NO_INIT aqui es diferente
de la que tenía en el ejemplo anterior 
41 rectangular * 42 _to_ptr(THIS) 43 rectangular THIS = NO_INITmientras que su colocación en la segunda parte - después de la lista de parámetros - inhibe la acción del
typemap,
su uso en la lista de
argumentos de la XSUB en un argumento opcional 
indica que no es necesario asignarle un valor por defecto.
Las líneas 368-370 del código generado para la XSUB muestran la conversión
correspondiente:
350 XS(XS_rectangularPtr_x)
351 {
352     dXSARGS;
353     if (items < 1 || items > 2)
354         Perl_croak(aTHX_ "Usage: rectangularPtr::x(THIS, __value = NO_INIT)");
355     {
356         rectangular *   THIS;
357         double  __value;
358         double  RETVAL;
359         dXSTARG;
360
361         if (sv_derived_from(ST(0), "rectangularPtr")) {
362             IV tmp = SvIV((SV*)SvRV(ST(0)));
363             THIS = INT2PTR(rectangular *,tmp);
364         }
365         else
366             Perl_croak(aTHX_ "THIS is not of type rectangularPtr");
367
368         if (items >= 2) {
369             __value = (double)SvNV(ST(1));
370         }
371 #line 67 "Coord.xs"
372         if (items > 1)
373             THIS->x = __value;
374         RETVAL = THIS->x;
375 #line 376 "Coord.c"
376         XSprePUSH; PUSHn((double)RETVAL);
377     }
378     XSRETURN(1);
379 }
La conversión mediante 
   T_PTROBJ
  
para rectangular * da lugar a
que la referencia Perl sea convertida en un entero mediante 
   SvIV
  
y el entero en un puntero C mediante 
   INT2PTR
  
(líneas 362-363).
Perl usa las macros 
   PTR2INT
   y INT2PTR
para convertir entre punteros e IVs.
El tipo entero de Perl 
   IV
   no es necesariamente 
igual al tipo int de C; La diferencia está en que 
Perl garantiza que el tipo entero tiene tamaño suficiente 
para guardar un puntero. Esta condición garantiza la
corrección del código del typemap T_PTROBJ:
| INPUT T_PTROBJ | Traducción | 
| 
if (sv_derived_from($arg, \"${ntype}\")) {
  IV tmp = SvIV((SV*)SvRV($arg));
  $var = INT2PTR($type,tmp);
}
else
  Perl_croak(aTHX_ 
   \"$var is not of type ${ntype}\")
 | 
if (sv_derived_from(ST(0), "rectangularPtr")) {
  IV tmp = SvIV((SV*)SvRV(ST(0)));
  THIS = INT2PTR(rectangular *,tmp);
}
else
  Perl_croak(aTHX_ 
    "THIS is not of type rectangularPtr");
 | 
El código para el campo y es similar al generado 
para x:
82 double 83 y(THIS, __value = NO_INIT) 84 rectangular * THIS 85 double __value 86 PROTOTYPE: $;$ 87 CODE: 88 if (items > 1) 89 THIS->y = __value; 90 RETVAL = THIS->y; 91 OUTPUT: 92 RETVAL 93 .. ............... identica estructura para polarLa siguiente sesión con el depurador muestra como la estructura permanece almacenada en el formato nativo en un valor escalar de tipo cadena:
lhp@nereida:~/Lperl/src/XSUB/h2xsexample/Coord/script$ perl -Mblib -MCoord -de 0
main::(-e:1):   0
  DB<1> $r=rectangular->new(); $rp = $r->_to_ptr()
  DB<2> $rp->x(4.5); $rp->y(3.2)
  DB<3> x $r
0  rectangular=SCALAR(0x8494068)
   -> "\c@\c@\c@\c@\c@\c@\cR\@\cI\@"
  DB<4> x pack("dd", (4.5, 3.2))
0  "\c@\c@\c@\c@\c@\c@\cR\@\cI\@"
  DB<5> x unpack("dd", $$r)
0  4.5
1  3.2
Casiano Rodríguez León
