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
[ XS code in package RPC ]
+The same package name can be used more than once, allowing for
+non-contiguous code. This is useful if you have a stronger ordering
+principle than package names.
+
Although this keyword is optional and in some cases provides redundant
information it should always be used. This keyword will ensure that the
XSUBs appear in the desired package.
is quietly ignored.
The following code demonstrates how to supply initialization code for
-function parameters. The initialization code is eval'd within double
+function parameters. The initialization code is eval'ed within double
quotes by the compiler before it is added to the output so anything
which should be interpreted literally [mainly C<$>, C<@>, or C<\\>]
must be protected with backslashes. The variables $var, $arg,
bool_t
rpcb_gettime(host,timep)
- char *host = (char *)SvPV($arg,PL_na);
+ char *host = (char *)SvPV_nolen($arg);
time_t &timep = 0;
OUTPUT:
timep
bool_t
rpcb_gettime(host,timep)
- time_t &timep ; /* \$v{timep}=@{[$v{timep}=$arg]} */
- char *host + SvOK($v{timep}) ? SvPV($arg,PL_na) : NULL;
+ time_t &timep; /* \$v{timep}=@{[$v{timep}=$arg]} */
+ char *host + SvOK($v{timep}) ? SvPV_nolen($arg) : NULL;
OUTPUT:
timep
my ($day, $month);
day_month($day, time, $month);
+=head2 The C<length(NAME)> Keyword
+
+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 omitted when
+the generated Perl function is called. E.g.,
+
+ void
+ dump_chars(char *s, short l)
+ {
+ short n = 0;
+ while (n < l) {
+ printf("s[%d] = \"\\%#03o\"\n", n, (int)s[n]);
+ n++;
+ }
+ }
+
+ MODULE = x PACKAGE = x
+
+ void dump_chars(char *s, short length(s))
+
+should be called as C<dump_chars($string)>.
+
+This directive is supported with ANSI-type function declarations only.
+
=head2 Variable-length Parameter Lists
XSUBs can have variable-length parameter lists by specifying an ellipsis
time_t timep = NO_INIT
PREINIT:
char *host = "localhost";
- STRLEN n_a;
CODE:
if( items > 1 )
- host = (char *)SvPV(ST(1), n_a);
+ host = (char *)SvPV_nolen(ST(1));
RETVAL = rpcb_gettime( host, &timep );
OUTPUT:
timep
time_t timep;
bool_t x;
CODE:
- ST(0) = sv_newmortal();
if( rpcb_gettime( host, &timep ) ){
+ ST(0) = sv_newmortal();
sv_setnv( ST(0), (double)timep);
}
else{
Some people may be inclined to include an explicit C<return> in the above
XSUB, rather than letting control fall through to the end. In those
situations C<XSRETURN_EMPTY> should be used, instead. This will ensure that
-the XSUB stack is properly adjusted. Consult L<perlguts/"API LISTING"> for
-other C<XSRETURN> macros.
+the XSUB stack is properly adjusted. Consult L<perlapi> for other
+C<XSRETURN> macros.
Since C<XSRETURN_*> macros can be used with CODE blocks as well, one can
rewrite this example as:
PROTOTYPE: $;$
PREINIT:
char *host = "localhost";
- STRLEN n_a;
CODE:
if( items > 1 )
- host = (char *)SvPV(ST(1), n_a);
+ host = (char *)SvPV_nolen(ST(1));
RETVAL = rpcb_gettime( host, &timep );
OUTPUT:
timep
RETVAL
+If the prototypes are enabled, you can disable it locally for a given
+XSUB as in the following example:
+
+ void
+ rpcb_gettime_noproto()
+ PROTOTYPE: DISABLE
+ ...
+
=head2 The ALIAS: Keyword
The ALIAS: keyword allows an XSUB to have two or more unique Perl names
OUTPUT:
timep
+=head2 The OVERLOAD: Keyword
+
+Instead of writing an overloaded interface using pure Perl, you
+can also use the OVERLOAD keyword to define additional Perl names
+for your functions (like the ALIAS: keyword above). However, the
+overloaded functions must be defined with three parameters (except
+for the nomethod() function which needs four parameters). If any
+function has the OVERLOAD: keyword, several additional lines
+will be defined in the c file generated by xsubpp in order to
+register with the overload magic.
+
+Since blessed objects are actually stored as RV's, it is useful
+to use the typemap features to preprocess parameters and extract
+the actual SV stored within the blessed RV. See the sample for
+T_PTROBJ_SPECIAL below.
+
+To use the OVERLOAD: keyword, create an XS function which takes
+three input parameters ( or use the c style '...' definition) like
+this:
+
+ SV *
+ cmp (lobj, robj, swap)
+ My_Module_obj lobj
+ My_Module_obj robj
+ IV swap
+ OVERLOAD: cmp <=>
+ { /* function defined here */}
+
+In this case, the function will overload both of the three way
+comparison operators. For all overload operations using non-alpha
+characters, you must type the parameter without quoting, separating
+multiple overloads with whitespace. Note that "" (the stringify
+overload) should be entered as \"\" (i.e. escaped).
+
+=head2 The FALLBACK: Keyword
+
+In addition to the OVERLOAD keyword, if you need to control how
+Perl autogenerates missing overloaded operators, you can set the
+FALLBACK keyword in the module header section, like this:
+
+ MODULE = RPC PACKAGE = RPC
+
+ FALLBACK: TRUE
+ ...
+
+where FALLBACK can take any of the three values TRUE, FALSE, or
+UNDEF. If you do not set any FALLBACK value when using OVERLOAD,
+it defaults to UNDEF. FALLBACK is not used except when one or
+more functions using OVERLOAD have been defined. Please see
+L<overload/Fallback> for more details.
+
=head2 The INTERFACE: Keyword
This keyword declares the current XSUB as a keeper of the given
C<subtract_off>. Then one can use
#define XSINTERFACE_FUNC_BYOFFSET(ret,cv,f) \
- ((XSINTERFACE_CVT(ret,))fp[CvXSUBANY(cv).any_i32])
+ ((XSINTERFACE_CVT_ANON(ret))fp[CvXSUBANY(cv).any_i32])
#define XSINTERFACE_FUNC_BYOFFSET_set(cv,f) \
CvXSUBANY(cv).any_i32 = CAT2( f, _off )
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
It is therefore strongly recommended that these macros be used by all
XS modules that make use of static data.
-The easiest way to get a template set of macros to use is by specifiying
+The easiest way to get a template set of macros to use is by specifying
the C<-g> (C<--global>) option with h2xs (see L<h2xs>).
Below is an example module that makes use of the macros.
#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"
-
+
/* Global Data */
-
+
#define MY_CXT_KEY "BlindMice::_guts" XS_VERSION
-
+
typedef struct {
int count;
char name[3][100];
} my_cxt_t;
-
+
START_MY_CXT
-
+
MODULE = BlindMice PACKAGE = BlindMice
-
+
BOOT:
{
MY_CXT_INIT;
dMY_CXT;
CODE:
if (MY_CXT.count >= 3) {
- warn("Already have 3 blind mice") ;
+ warn("Already have 3 blind mice");
RETVAL = 0;
}
else {
else
RETVAL = newSVpv(MY_CXT.name[index - 1]);
+ void
+ CLONE(...)
+ CODE:
+ MY_CXT_CLONE;
B<REFERENCE>
The MY_CXT_INIT macro initialises storage for the C<my_cxt_t> struct.
-It I<must> be called exactly once -- typically in a BOOT: section.
+It I<must> be called exactly once -- typically in a BOOT: section. If you
+are maintaining multiple interpreters, it should be called once in each
+interpreter instance, except for interpreters cloned from existing ones.
+(But see C<MY_CXT_CLONE> below.)
=item dMY_CXT
dMY_CXT;
MY_CXT.index = 2;
+=item aMY_CXT/pMY_CXT
+
+C<dMY_CXT> may be quite expensive to calculate, and to avoid the overhead
+of invoking it in each function it is possible to pass the declaration
+onto other functions using the C<aMY_CXT>/C<pMY_CXT> macros, eg
+
+ void sub1() {
+ dMY_CXT;
+ MY_CXT.index = 1;
+ sub2(aMY_CXT);
+ }
+
+ void sub2(pMY_CXT) {
+ MY_CXT.index = 2;
+ }
+
+Analogously to C<pTHX>, there are equivalent forms for when the macro is the
+first or last in multiple arguments, where an underscore represents a
+comma, i.e. C<_aMY_CXT>, C<aMY_CXT_>, C<_pMY_CXT> and C<pMY_CXT_>.
+
+=item MY_CXT_CLONE
+
+By default, when a new interpreter is created as a copy of an existing one
+(eg via C<< threads->create() >>), both interpreters share the same physical
+my_cxt_t structure. Calling C<MY_CXT_CLONE> (typically via the package's
+C<CLONE()> function), causes a byte-for-byte copy of the structure to be
+taken, and any future dMY_CXT will cause the copy to be accessed instead.
+
+=item MY_CXT_INIT_INTERP(my_perl)
+
+=item dMY_CXT_INTERP(my_perl)
+
+These are versions of the macros which take an explicit interpreter as an
+argument.
+
=back
+Note that these macros will only work together within the I<same> source
+file; that is, a dMY_CTX in one source file will access a different structure
+than a dMY_CTX in another source file.
+
+=head2 Thread-aware system interfaces
+
+Starting from Perl 5.8, in C/C++ level Perl knows how to wrap
+system/library interfaces that have thread-aware versions
+(e.g. getpwent_r()) into frontend macros (e.g. getpwent()) that
+correctly handle the multithreaded interaction with the Perl
+interpreter. This will happen transparently, the only thing
+you need to do is to instantiate a Perl interpreter.
+
+This wrapping happens always when compiling Perl core source
+(PERL_CORE is defined) or the Perl core extensions (PERL_EXT is
+defined). When compiling XS code outside of Perl core the wrapping
+does not take place. Note, however, that intermixing the _r-forms
+(as Perl compiled for multithreaded operation will do) and the _r-less
+forms is neither well-defined (inconsistent results, data corruption,
+or even crashes become more likely), nor is it very portable.
+
=head1 EXAMPLES
File C<RPC.xs>: Interface to some ONC+ RPC bind library functions.