NO_OUTPUT int
delete_file(char *name)
- POST_CALL:
+ POSTCALL:
if (RETVAL != 0)
croak("Error %d while deleting file '%s'", RETVAL, name);
C<h = host> is not performed too early. Otherwise one would need to have the
assignment C<h = host> in a CODE: or INIT: section.)
-=head2 The IN/OUTLIST/IN_OUTLIST Keywords
+=head2 The IN/OUTLIST/IN_OUTLIST/OUT/IN_OUT Keywords
In the list of parameters for an XSUB, one can precede parameter names
-by the C<IN>/C<OUTLIST>/C<IN_OUTLIST> keywords. C<IN> keyword is a default,
-the other two keywords indicate how the Perl interface should differ from
-the C interface.
-
-Parameters preceded by C<OUTLIST>/C<IN_OUTLIST> keywords are considered to
-be used by the C subroutine I<via pointers>. C<OUTLIST> keyword indicates
-that the C subroutine does not inspect the memory pointed by this parameter,
-but will write through this pointer to provide additional return values.
-Such parameters do not appear in the usage signature of the generated Perl
-function.
-
-Parameters preceded by C<IN_OUTLIST> I<do> appear as parameters to the
-Perl function. These parameters are converted to the corresponding C type,
-then pointers to these data are given as arguments to the C function. It
-is expected that the C function will write through these pointers
+by the C<IN>/C<OUTLIST>/C<IN_OUTLIST>/C<OUT>/C<IN_OUT> keywords.
+C<IN> keyword is the default, the other keywords indicate how the Perl
+interface should differ from the C interface.
+
+Parameters preceded by C<OUTLIST>/C<IN_OUTLIST>/C<OUT>/C<IN_OUT>
+keywords are considered to be used by the C subroutine I<via
+pointers>. C<OUTLIST>/C<OUT> keywords indicate that the C subroutine
+does not inspect the memory pointed by this parameter, but will write
+through this pointer to provide additional return values.
+
+Parameters preceded by C<OUTLIST> keyword do not appear in the usage
+signature of the generated Perl function.
+
+Parameters preceded by C<IN_OUTLIST>/C<IN_OUT>/C<OUT> I<do> appear as
+parameters to the Perl function. With the exception of
+C<OUT>-parameters, these parameters are converted to the corresponding
+C type, then pointers to these data are given as arguments to the C
+function. It is expected that the C function will write through these
+pointers.
The return list of the generated Perl function consists of the C return value
from the function (unless the XSUB is of C<void> return type or
-C<The NO_INIT Keyword> was used) followed by all the C<OUTLIST>
-and C<IN_OUTLIST> parameters (in the order of appearance). Say, an XSUB
+C<The NO_OUTPUT Keyword> was used) followed by all the C<OUTLIST>
+and C<IN_OUTLIST> parameters (in the order of appearance). On the
+return from the XSUB the C<IN_OUT>/C<OUT> Perl parameter will be
+modified to have the values written by the C function.
+
+For example, an XSUB
void
day_month(OUTLIST day, IN unix_time, OUTLIST month)
void day_month(int *day, int unix_time, int *month);
-The C<in>/C<OUTLIST>/C<IN_OUTLIST> keywords can be mixed with ANSI-style
-declarations, as in
+The C<IN>/C<OUTLIST>/C<IN_OUTLIST>/C<IN_OUT>/C<OUT> keywords can be
+mixed with ANSI-style declarations, as in
void
day_month(OUTLIST int day, int unix_time, OUTLIST int month)
(here the optional C<IN> keyword is omitted).
-The C<IN_OUTLIST> parameters are somewhat similar to parameters introduced
-with L<The & Unary Operator> and put into the C<OUTPUT:> section (see
-L<The OUTPUT: Keyword>). Say, the same C function can be interfaced with as
+The C<IN_OUT> parameters are identical with parameters introduced with
+L<The & Unary Operator> and put into the C<OUTPUT:> section (see
+L<The OUTPUT: Keyword>). The C<IN_OUTLIST> parameters are very similar,
+the only difference being that the value C function writes through the
+pointer would not modify the Perl parameter, but is put in the output
+list.
+
+The C<OUTLIST>/C<OUT> parameter differ from C<IN_OUTLIST>/C<IN_OUT>
+parameters only by the initial value of the Perl parameter not
+being read (and not being given to the C function - which gets some
+garbage instead). For example, the same C function as above can be
+interfaced with as
+
+ void day_month(OUT int day, int unix_time, OUT int month);
+
+or
void
day_month(day, unix_time, month)
OUTPUT:
RETVAL
-In fact, one can put this check into a POST_CALL: section as well. Together
+In fact, one can put this check into a POSTCALL: section as well. Together
with PREINIT: simplifications, this leads to:
int
rpcb_gettime(host)
char *host
time_t timep;
- POST_CALL:
+ POSTCALL:
if (RETVAL == 0)
XSRETURN_UNDEF;
code specified for the cleanup block will be added as the last statements
in the XSUB.
-=head2 The POST_CALL: Keyword
+=head2 The POSTCALL: Keyword
This keyword can be used when an XSUB requires special procedures
-executed after the C subroutine call is performed. When the POST_CALL:
+executed after the C subroutine call is performed. When the POSTCALL:
keyword is used it must precede OUTPUT: and CLEANUP: blocks which are
present in the XSUB.
-The POST_CALL: block does not make a lot of sense when the C subroutine
+See examples in L<"The NO_OUTPUT Keyword"> and L<"Returning Undef And Empty Lists">.
+
+The POSTCALL: block does not make a lot of sense when the C subroutine
call is supplied by user by providing either CODE: or PPCODE: section.
=head2 The BOOT: Keyword
This is useful to avoid a CODE: block for a C function which takes a parameter
by reference. Typically, the parameter should be not a pointer type (an
-C<int> or C<long> but not a C<int*> or C<long*>).
+C<int> or C<long> but not an C<int*> or C<long*>).
The following XSUB will generate incorrect C code. The B<xsubpp> compiler will
turn this into code which calls C<rpcb_gettime()> with parameters C<(char
=head2 Inserting POD, Comments and C Preprocessor Directives
C preprocessor directives are allowed within BOOT:, PREINIT: INIT:, CODE:,
-PPCODE:, POST_CALL:, and CLEANUP: blocks, as well as outside the functions.
+PPCODE:, POSTCALL:, and CLEANUP: blocks, as well as outside the functions.
Comments are allowed anywhere after the MODULE keyword. The compiler will
pass the preprocessor directives through untouched and will remove the
commented lines. POD documentation is allowed at any point, both in the
candidates to return undef or an empty list in case of failure. If the
failure may be detected without a call to the C function, you may want to use
an INIT: section to report the failure. For failures detectable after the C
-function returns one may want to use a POST_CALL: section to process the
+function returns one may want to use a POSTCALL: section to process the
failure. In more complicated cases use CODE: or PPCODE: sections.
If many functions use the same failure indication based on the return value,
on the fly, giving the desired effect. This example demonstrates some
of the power and versatility of the typemap facility.
+=head2 Safely Storing Static Data in XS
+
+Starting with Perl 5.8, a macro framework has been defined to allow
+static data to be safely stored in XS modules that will be accessed from
+a multi-threaded Perl.
+
+Although primarily designed for use with multi-threaded Perl, the macros
+have been designed so that they will work with non-threaded Perl as well.
+
+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 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;
+ MY_CXT.count = 0;
+ strcpy(MY_CXT.name[0], "None");
+ strcpy(MY_CXT.name[1], "None");
+ strcpy(MY_CXT.name[2], "None");
+ }
+
+ int
+ newMouse(char * name)
+ char * name;
+ PREINIT:
+ dMY_CXT;
+ CODE:
+ if (MY_CXT.count >= 3) {
+ warn("Already have 3 blind mice") ;
+ RETVAL = 0;
+ }
+ else {
+ RETVAL = ++ MY_CXT.count;
+ strcpy(MY_CXT.name[MY_CXT.count - 1], name);
+ }
+
+ char *
+ get_mouse_name(index)
+ int index
+ CODE:
+ dMY_CXT;
+ RETVAL = MY_CXT.lives ++;
+ if (index > MY_CXT.count)
+ croak("There are only 3 blind mice.");
+ else
+ RETVAL = newSVpv(MY_CXT.name[index - 1]);
+
+
+B<REFERENCE>
+
+=over 5
+
+=item MY_CXT_KEY
+
+This macro is used to define a unique key to refer to the static data
+for an XS module. The suggested naming scheme, as used by h2xs, is to
+use a string that consists of the module name, the string "::_guts"
+and the module version number.
+
+ #define MY_CXT_KEY "MyModule::_guts" XS_VERSION
+
+=item typedef my_cxt_t
+
+This struct typedef I<must> always be called C<my_cxt_t> -- the other
+C<CXT*> macros assume the existence of the C<my_cxt_t> typedef name.
+
+Declare a typedef named C<my_cxt_t> that is a structure that contains
+all the data that needs to be interpreter-local.
+
+ typedef struct {
+ int some_value;
+ } my_cxt_t;
+
+=item START_MY_CXT
+
+Always place the START_MY_CXT macro directly after the declaration
+of C<my_cxt_t>.
+
+=item MY_CXT_INIT
+
+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.
+
+=item dMY_CXT
+
+Use the dMY_CXT macro (a declaration) in all the functions that access
+MY_CXT.
+
+=item MY_CXT
+
+Use the MY_CXT macro to access members of the C<my_cxt_t> struct. For
+example, if C<my_cxt_t> is
+
+ typedef struct {
+ int index;
+ } my_cxt_t;
+
+then use this to access the C<index> member
+
+ dMY_CXT;
+ MY_CXT.index = 2;
+
+=back
+
=head1 EXAMPLES
File C<RPC.xs>: Interface to some ONC+ RPC bind library functions.