and "old-practice-declared-as-void" functions. Hence your code is at
mercy of this heuristics unless you use C<SV *> as return value.)
+=head2 Returning SVs, AVs and HVs through RETVAL
+
+When you're using RETVAL to return an C<SV *>, there's some magic
+going on behind the scenes that should be mentioned. When you're
+manipulating the argument stack using the ST(x) macro, for example,
+you usually have to pay special attention to reference counts. (For
+more about reference counts, see L<perlguts>.) To make your life
+easier, the typemap file automatically makes C<RETVAL> mortal when
+you're returning an C<SV *>. Thus, the following two XSUBs are more
+or less equivalent:
+
+ void
+ alpha()
+ PPCODE:
+ ST(0) = newSVpv("Hello World",0);
+ sv_2mortal(ST(0));
+ XSRETURN(1);
+
+ SV *
+ beta()
+ CODE:
+ RETVAL = newSVpv("Hello World",0);
+ OUTPUT:
+ RETVAL
+
+This is quite useful as it usually improves readability. While
+this works fine for an C<SV *>, it's unfortunately not as easy
+to have C<AV *> or C<HV *> as a return value. You I<should> be
+able to write:
+
+ AV *
+ array()
+ CODE:
+ RETVAL = newAV();
+ /* do something with RETVAL */
+ OUTPUT:
+ RETVAL
+
+But due to an unfixable bug (fixing it would break lots of existing
+CPAN modules) in the typemap file, the reference count of the C<AV *>
+is not properly decremented. Thus, the above XSUB would leak memory
+whenever it is being called. The same problem exists for C<HV *>.
+
+When you're returning an C<AV *> or a C<HV *>, you have make sure
+their reference count is decremented by making the AV or HV mortal:
+
+ AV *
+ array()
+ CODE:
+ RETVAL = newAV();
+ sv_2mortal((SV*)RETVAL);
+ /* do something with RETVAL */
+ OUTPUT:
+ RETVAL
+
+And also remember that you don't have to do this for an C<SV *>.
+
=head2 The MODULE Keyword
The MODULE keyword is used to start the XS code and to specify the package
bool_t
rpcb_gettime(host,timep)
- time_t &timep ; /* \$v{timep}=@{[$v{timep}=$arg]} */
+ time_t &timep; /* \$v{timep}=@{[$v{timep}=$arg]} */
char *host + SvOK($v{timep}) ? SvPV($arg,PL_na) : NULL;
OUTPUT:
timep
If one of the input arguments to the C function is the length of a string
argument C<NAME>, one can substitute the name of the length-argument by
-C<length(NAME)> in the XSUB declaration. This argument must be omited when
+C<length(NAME)> in the XSUB declaration. This argument must be omitted when
the generated Perl function is called. E.g.,
void
T_PTROBJ_SPECIAL
if (sv_derived_from($arg, \"${(my $ntt=$ntype)=~s/_/::/g;\$ntt}\")) {
IV tmp = SvIV((SV*)SvRV($arg));
- $var = ($type) tmp;
+ $var = INT2PTR($type, tmp);
}
else
croak(\"$var is not of type ${(my $ntt=$ntype)=~s/_/::/g;\$ntt}\")
on the fly, giving the desired effect. This example demonstrates some
of the power and versatility of the typemap facility.
+The INT2PTR macro (defined in perl.h) casts an integer to a pointer,
+of a given type, taking care of the possible different size of integers
+and pointers. There are also PTR2IV, PTR2UV, PTR2NV macros,
+to map the other way, which may be useful in OUTPUT sections.
+
=head2 Safely Storing Static Data in XS
Starting with Perl 5.8, a macro framework has been defined to allow
dMY_CXT;
CODE:
if (MY_CXT.count >= 3) {
- warn("Already have 3 blind mice") ;
+ warn("Already have 3 blind mice");
RETVAL = 0;
}
else {