1640 lines
56 KiB
Plaintext
1640 lines
56 KiB
Plaintext
=head1 NAME
|
|
|
|
perlxs - XS language reference manual
|
|
|
|
=head1 DESCRIPTION
|
|
|
|
=head2 Introduction
|
|
|
|
XS is an interface description file format used to create an extension
|
|
interface between Perl and C code (or a C library) which one wishes
|
|
to use with Perl. The XS interface is combined with the library to
|
|
create a new library which can then be either dynamically loaded
|
|
or statically linked into perl. The XS interface description is
|
|
written in the XS language and is the core component of the Perl
|
|
extension interface.
|
|
|
|
An B<XSUB> forms the basic unit of the XS interface. After compilation
|
|
by the B<xsubpp> compiler, each XSUB amounts to a C function definition
|
|
which will provide the glue between Perl calling conventions and C
|
|
calling conventions.
|
|
|
|
The glue code pulls the arguments from the Perl stack, converts these
|
|
Perl values to the formats expected by a C function, call this C function,
|
|
transfers the return values of the C function back to Perl.
|
|
Return values here may be a conventional C return value or any C
|
|
function arguments that may serve as output parameters. These return
|
|
values may be passed back to Perl either by putting them on the
|
|
Perl stack, or by modifying the arguments supplied from the Perl side.
|
|
|
|
The above is a somewhat simplified view of what really happens. Since
|
|
Perl allows more flexible calling conventions than C, XSUBs may do much
|
|
more in practice, such as checking input parameters for validity,
|
|
throwing exceptions (or returning undef/empty list) if the return value
|
|
from the C function indicates failure, calling different C functions
|
|
based on numbers and types of the arguments, providing an object-oriented
|
|
interface, etc.
|
|
|
|
Of course, one could write such glue code directly in C. However, this
|
|
would be a tedious task, especially if one needs to write glue for
|
|
multiple C functions, and/or one is not familiar enough with the Perl
|
|
stack discipline and other such arcana. XS comes to the rescue here:
|
|
instead of writing this glue C code in long-hand, one can write
|
|
a more concise short-hand I<description> of what should be done by
|
|
the glue, and let the XS compiler B<xsubpp> handle the rest.
|
|
|
|
The XS language allows one to describe the mapping between how the C
|
|
routine is used, and how the corresponding Perl routine is used. It
|
|
also allows creation of Perl routines which are directly translated to
|
|
C code and which are not related to a pre-existing C function. In cases
|
|
when the C interface coincides with the Perl interface, the XSUB
|
|
declaration is almost identical to a declaration of a C function (in K&R
|
|
style). In such circumstances, there is another tool called C<h2xs>
|
|
that is able to translate an entire C header file into a corresponding
|
|
XS file that will provide glue to the functions/macros described in
|
|
the header file.
|
|
|
|
The XS compiler is called B<xsubpp>. This compiler creates
|
|
the constructs necessary to let an XSUB manipulate Perl values, and
|
|
creates the glue necessary to let Perl call the XSUB. The compiler
|
|
uses B<typemaps> to determine how to map C function parameters
|
|
and output values to Perl values and back. The default typemap
|
|
(which comes with Perl) handles many common C types. A supplementary
|
|
typemap may also be needed to handle any special structures and types
|
|
for the library being linked.
|
|
|
|
A file in XS format starts with a C language section which goes until the
|
|
first C<MODULE =Z<>> directive. Other XS directives and XSUB definitions
|
|
may follow this line. The "language" used in this part of the file
|
|
is usually referred to as the XS language.
|
|
|
|
See L<perlxstut> for a tutorial on the whole extension creation process.
|
|
|
|
Note: For some extensions, Dave Beazley's SWIG system may provide a
|
|
significantly more convenient mechanism for creating the extension glue
|
|
code. See L<http://www.swig.org> for more
|
|
information.
|
|
|
|
=head2 On The Road
|
|
|
|
Many of the examples which follow will concentrate on creating an interface
|
|
between Perl and the ONC+ RPC bind library functions. The rpcb_gettime()
|
|
function is used to demonstrate many features of the XS language. This
|
|
function has two parameters; the first is an input parameter and the second
|
|
is an output parameter. The function also returns a status value.
|
|
|
|
bool_t rpcb_gettime(const char *host, time_t *timep);
|
|
|
|
From C this function will be called with the following
|
|
statements.
|
|
|
|
#include <rpc/rpc.h>
|
|
bool_t status;
|
|
time_t timep;
|
|
status = rpcb_gettime( "localhost", &timep );
|
|
|
|
If an XSUB is created to offer a direct translation between this function
|
|
and Perl, then this XSUB will be used from Perl with the following code.
|
|
The $status and $timep variables will contain the output of the function.
|
|
|
|
use RPC;
|
|
$status = rpcb_gettime( "localhost", $timep );
|
|
|
|
The following XS file shows an XS subroutine, or XSUB, which
|
|
demonstrates one possible interface to the rpcb_gettime()
|
|
function. This XSUB represents a direct translation between
|
|
C and Perl and so preserves the interface even from Perl.
|
|
This XSUB will be invoked from Perl with the usage shown
|
|
above. Note that the first three #include statements, for
|
|
C<EXTERN.h>, C<perl.h>, and C<XSUB.h>, will always be present at the
|
|
beginning of an XS file. This approach and others will be
|
|
expanded later in this document.
|
|
|
|
#include "EXTERN.h"
|
|
#include "perl.h"
|
|
#include "XSUB.h"
|
|
#include <rpc/rpc.h>
|
|
|
|
MODULE = RPC PACKAGE = RPC
|
|
|
|
bool_t
|
|
rpcb_gettime(host,timep)
|
|
char *host
|
|
time_t &timep
|
|
OUTPUT:
|
|
timep
|
|
|
|
Any extension to Perl, including those containing XSUBs,
|
|
should have a Perl module to serve as the bootstrap which
|
|
pulls the extension into Perl. This module will export the
|
|
extension's functions and variables to the Perl program and
|
|
will cause the extension's XSUBs to be linked into Perl.
|
|
The following module will be used for most of the examples
|
|
in this document and should be used from Perl with the C<use>
|
|
command as shown earlier. Perl modules are explained in
|
|
more detail later in this document.
|
|
|
|
package RPC;
|
|
|
|
require Exporter;
|
|
require DynaLoader;
|
|
@ISA = qw(Exporter DynaLoader);
|
|
@EXPORT = qw( rpcb_gettime );
|
|
|
|
bootstrap RPC;
|
|
1;
|
|
|
|
Throughout this document a variety of interfaces to the rpcb_gettime()
|
|
XSUB will be explored. The XSUBs will take their parameters in different
|
|
orders or will take different numbers of parameters. In each case the
|
|
XSUB is an abstraction between Perl and the real C rpcb_gettime()
|
|
function, and the XSUB must always ensure that the real rpcb_gettime()
|
|
function is called with the correct parameters. This abstraction will
|
|
allow the programmer to create a more Perl-like interface to the C
|
|
function.
|
|
|
|
=head2 The Anatomy of an XSUB
|
|
|
|
The simplest XSUBs consist of 3 parts: a description of the return
|
|
value, the name of the XSUB routine and the names of its arguments,
|
|
and a description of types or formats of the arguments.
|
|
|
|
The following XSUB allows a Perl program to access a C library function
|
|
called sin(). The XSUB will imitate the C function which takes a single
|
|
argument and returns a single value.
|
|
|
|
double
|
|
sin(x)
|
|
double x
|
|
|
|
When using parameters with C pointer types, as in
|
|
|
|
double string_to_double(char *s);
|
|
|
|
there may be two ways to describe this argument to B<xsubpp>:
|
|
|
|
char * s
|
|
char &s
|
|
|
|
Both these XS declarations correspond to the C<char*> C type, but they have
|
|
different semantics. It is convenient to think that the indirection operator
|
|
C<*> should be considered as a part of the type and the address operator C<&>
|
|
should be considered part of the variable. See L<"The Typemap"> and
|
|
L<"The & Unary Operator"> for more info about handling qualifiers and unary
|
|
operators in C types.
|
|
|
|
The function name and the return type must be placed on
|
|
separate lines and should be flush left-adjusted.
|
|
|
|
INCORRECT CORRECT
|
|
|
|
double sin(x) double
|
|
double x sin(x)
|
|
double x
|
|
|
|
The function body may be indented or left-adjusted. The following example
|
|
shows a function with its body left-adjusted. Most examples in this
|
|
document will indent the body for better readability.
|
|
|
|
CORRECT
|
|
|
|
double
|
|
sin(x)
|
|
double x
|
|
|
|
More complicated XSUBs may contain many other sections. Each section of
|
|
an XSUB starts with the corresponding keyword, such as INIT: or CLEANUP:.
|
|
However, the first two lines of an XSUB always contain the same data:
|
|
descriptions of the return type and the names of the function and its
|
|
parameters. Whatever immediately follows these is considered to be
|
|
an INPUT: section unless explicitly marked with another keyword.
|
|
(See L<The INPUT: Keyword>.)
|
|
|
|
An XSUB section continues until another section-start keyword is found.
|
|
|
|
=head2 The Argument Stack
|
|
|
|
The Perl argument stack is used to store the values which are
|
|
sent as parameters to the XSUB and to store the XSUB's
|
|
return value(s). In reality all Perl functions (including non-XSUB
|
|
ones) keep their values on this stack all the same time, each limited
|
|
to its own range of positions on the stack. In this document the
|
|
first position on that stack which belongs to the active
|
|
function will be referred to as position 0 for that function.
|
|
|
|
XSUBs refer to their stack arguments with the macro B<ST(x)>, where I<x>
|
|
refers to a position in this XSUB's part of the stack. Position 0 for that
|
|
function would be known to the XSUB as ST(0). The XSUB's incoming
|
|
parameters and outgoing return values always begin at ST(0). For many
|
|
simple cases the B<xsubpp> compiler will generate the code necessary to
|
|
handle the argument stack by embedding code fragments found in the
|
|
typemaps. In more complex cases the programmer must supply the code.
|
|
|
|
=head2 The RETVAL Variable
|
|
|
|
The RETVAL variable is a special C variable that is declared automatically
|
|
for you. The C type of RETVAL matches the return type of the C library
|
|
function. The B<xsubpp> compiler will declare this variable in each XSUB
|
|
with non-C<void> return type. By default the generated C function
|
|
will use RETVAL to hold the return value of the C library function being
|
|
called. In simple cases the value of RETVAL will be placed in ST(0) of
|
|
the argument stack where it can be received by Perl as the return value
|
|
of the XSUB.
|
|
|
|
If the XSUB has a return type of C<void> then the compiler will
|
|
not declare a RETVAL variable for that function. When using
|
|
a PPCODE: section no manipulation of the RETVAL variable is required, the
|
|
section may use direct stack manipulation to place output values on the stack.
|
|
|
|
If PPCODE: directive is not used, C<void> return value should be used
|
|
only for subroutines which do not return a value, I<even if> CODE:
|
|
directive is used which sets ST(0) explicitly.
|
|
|
|
Older versions of this document recommended to use C<void> return
|
|
value in such cases. It was discovered that this could lead to
|
|
segfaults in cases when XSUB was I<truly> C<void>. This practice is
|
|
now deprecated, and may be not supported at some future version. Use
|
|
the return value C<SV *> in such cases. (Currently C<xsubpp> contains
|
|
some heuristic code which tries to disambiguate between "truly-void"
|
|
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 The MODULE Keyword
|
|
|
|
The MODULE keyword is used to start the XS code and to
|
|
specify the package of the functions which are being
|
|
defined. All text preceding the first MODULE keyword is
|
|
considered C code and is passed through to the output
|
|
untouched. Every XS module will have a bootstrap function
|
|
which is used to hook the XSUBs into Perl. The package name
|
|
of this bootstrap function will match the value of the last
|
|
MODULE statement in the XS source files. The value of
|
|
MODULE should always remain constant within the same XS
|
|
file, though this is not required.
|
|
|
|
The following example will start the XS code and will place
|
|
all functions in a package named RPC.
|
|
|
|
MODULE = RPC
|
|
|
|
=head2 The PACKAGE Keyword
|
|
|
|
When functions within an XS source file must be separated into packages
|
|
the PACKAGE keyword should be used. This keyword is used with the MODULE
|
|
keyword and must follow immediately after it when used.
|
|
|
|
MODULE = RPC PACKAGE = RPC
|
|
|
|
[ XS code in package RPC ]
|
|
|
|
MODULE = RPC PACKAGE = RPCB
|
|
|
|
[ XS code in package RPCB ]
|
|
|
|
MODULE = RPC PACKAGE = RPC
|
|
|
|
[ XS code in package RPC ]
|
|
|
|
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.
|
|
|
|
=head2 The PREFIX Keyword
|
|
|
|
The PREFIX keyword designates prefixes which should be
|
|
removed from the Perl function names. If the C function is
|
|
C<rpcb_gettime()> and the PREFIX value is C<rpcb_> then Perl will
|
|
see this function as C<gettime()>.
|
|
|
|
This keyword should follow the PACKAGE keyword when used.
|
|
If PACKAGE is not used then PREFIX should follow the MODULE
|
|
keyword.
|
|
|
|
MODULE = RPC PREFIX = rpc_
|
|
|
|
MODULE = RPC PACKAGE = RPCB PREFIX = rpcb_
|
|
|
|
=head2 The OUTPUT: Keyword
|
|
|
|
The OUTPUT: keyword indicates that certain function parameters should be
|
|
updated (new values made visible to Perl) when the XSUB terminates or that
|
|
certain values should be returned to the calling Perl function. For
|
|
simple functions which have no CODE: or PPCODE: section,
|
|
such as the sin() function above, the RETVAL variable is
|
|
automatically designated as an output value. For more complex functions
|
|
the B<xsubpp> compiler will need help to determine which variables are output
|
|
variables.
|
|
|
|
This keyword will normally be used to complement the CODE: keyword.
|
|
The RETVAL variable is not recognized as an output variable when the
|
|
CODE: keyword is present. The OUTPUT: keyword is used in this
|
|
situation to tell the compiler that RETVAL really is an output
|
|
variable.
|
|
|
|
The OUTPUT: keyword can also be used to indicate that function parameters
|
|
are output variables. This may be necessary when a parameter has been
|
|
modified within the function and the programmer would like the update to
|
|
be seen by Perl.
|
|
|
|
bool_t
|
|
rpcb_gettime(host,timep)
|
|
char *host
|
|
time_t &timep
|
|
OUTPUT:
|
|
timep
|
|
|
|
The OUTPUT: keyword will also allow an output parameter to
|
|
be mapped to a matching piece of code rather than to a
|
|
typemap.
|
|
|
|
bool_t
|
|
rpcb_gettime(host,timep)
|
|
char *host
|
|
time_t &timep
|
|
OUTPUT:
|
|
timep sv_setnv(ST(1), (double)timep);
|
|
|
|
B<xsubpp> emits an automatic C<SvSETMAGIC()> for all parameters in the
|
|
OUTPUT section of the XSUB, except RETVAL. This is the usually desired
|
|
behavior, as it takes care of properly invoking 'set' magic on output
|
|
parameters (needed for hash or array element parameters that must be
|
|
created if they didn't exist). If for some reason, this behavior is
|
|
not desired, the OUTPUT section may contain a C<SETMAGIC: DISABLE> line
|
|
to disable it for the remainder of the parameters in the OUTPUT section.
|
|
Likewise, C<SETMAGIC: ENABLE> can be used to reenable it for the
|
|
remainder of the OUTPUT section. See L<perlguts> for more details
|
|
about 'set' magic.
|
|
|
|
=head2 The CODE: Keyword
|
|
|
|
This keyword is used in more complicated XSUBs which require
|
|
special handling for the C function. The RETVAL variable is
|
|
still declared, but it will not be returned unless it is specified
|
|
in the OUTPUT: section.
|
|
|
|
The following XSUB is for a C function which requires special handling of
|
|
its parameters. The Perl usage is given first.
|
|
|
|
$status = rpcb_gettime( "localhost", $timep );
|
|
|
|
The XSUB follows.
|
|
|
|
bool_t
|
|
rpcb_gettime(host,timep)
|
|
char *host
|
|
time_t timep
|
|
CODE:
|
|
RETVAL = rpcb_gettime( host, &timep );
|
|
OUTPUT:
|
|
timep
|
|
RETVAL
|
|
|
|
=head2 The INIT: Keyword
|
|
|
|
The INIT: keyword allows initialization to be inserted into the XSUB before
|
|
the compiler generates the call to the C function. Unlike the CODE: keyword
|
|
above, this keyword does not affect the way the compiler handles RETVAL.
|
|
|
|
bool_t
|
|
rpcb_gettime(host,timep)
|
|
char *host
|
|
time_t &timep
|
|
INIT:
|
|
printf("# Host is %s\n", host );
|
|
OUTPUT:
|
|
timep
|
|
|
|
Another use for the INIT: section is to check for preconditions before
|
|
making a call to the C function:
|
|
|
|
long long
|
|
lldiv(a,b)
|
|
long long a
|
|
long long b
|
|
INIT:
|
|
if (a == 0 && b == 0)
|
|
XSRETURN_UNDEF;
|
|
if (b == 0)
|
|
croak("lldiv: cannot divide by 0");
|
|
|
|
=head2 The NO_INIT Keyword
|
|
|
|
The NO_INIT keyword is used to indicate that a function
|
|
parameter is being used only as an output value. The B<xsubpp>
|
|
compiler will normally generate code to read the values of
|
|
all function parameters from the argument stack and assign
|
|
them to C variables upon entry to the function. NO_INIT
|
|
will tell the compiler that some parameters will be used for
|
|
output rather than for input and that they will be handled
|
|
before the function terminates.
|
|
|
|
The following example shows a variation of the rpcb_gettime() function.
|
|
This function uses the timep variable only as an output variable and does
|
|
not care about its initial contents.
|
|
|
|
bool_t
|
|
rpcb_gettime(host,timep)
|
|
char *host
|
|
time_t &timep = NO_INIT
|
|
OUTPUT:
|
|
timep
|
|
|
|
=head2 Initializing Function Parameters
|
|
|
|
C function parameters are normally initialized with their values from
|
|
the argument stack (which in turn contains the parameters that were
|
|
passed to the XSUB from Perl). The typemaps contain the
|
|
code segments which are used to translate the Perl values to
|
|
the C parameters. The programmer, however, is allowed to
|
|
override the typemaps and supply alternate (or additional)
|
|
initialization code. Initialization code starts with the first
|
|
C<=>, C<;> or C<+> on a line in the INPUT: section. The only
|
|
exception happens if this C<;> terminates the line, then this C<;>
|
|
is quietly ignored.
|
|
|
|
The following code demonstrates how to supply initialization code for
|
|
function parameters. The initialization code is eval'd 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,
|
|
and $type can be used as in typemaps.
|
|
|
|
bool_t
|
|
rpcb_gettime(host,timep)
|
|
char *host = (char *)SvPV($arg,PL_na);
|
|
time_t &timep = 0;
|
|
OUTPUT:
|
|
timep
|
|
|
|
This should not be used to supply default values for parameters. One
|
|
would normally use this when a function parameter must be processed by
|
|
another library function before it can be used. Default parameters are
|
|
covered in the next section.
|
|
|
|
If the initialization begins with C<=>, then it is output in
|
|
the declaration for the input variable, replacing the initialization
|
|
supplied by the typemap. If the initialization
|
|
begins with C<;> or C<+>, then it is performed after
|
|
all of the input variables have been declared. In the C<;>
|
|
case the initialization normally supplied by the typemap is not performed.
|
|
For the C<+> case, the declaration for the variable will include the
|
|
initialization from the typemap. A global
|
|
variable, C<%v>, is available for the truly rare case where
|
|
information from one initialization is needed in another
|
|
initialization.
|
|
|
|
Here's a truly obscure example:
|
|
|
|
bool_t
|
|
rpcb_gettime(host,timep)
|
|
time_t &timep ; /* \$v{timep}=@{[$v{timep}=$arg]} */
|
|
char *host + SvOK($v{timep}) ? SvPV($arg,PL_na) : NULL;
|
|
OUTPUT:
|
|
timep
|
|
|
|
The construct C<\$v{timep}=@{[$v{timep}=$arg]}> used in the above
|
|
example has a two-fold purpose: first, when this line is processed by
|
|
B<xsubpp>, the Perl snippet C<$v{timep}=$arg> is evaluated. Second,
|
|
the text of the evaluated snippet is output into the generated C file
|
|
(inside a C comment)! During the processing of C<char *host> line,
|
|
$arg will evaluate to C<ST(0)>, and C<$v{timep}> will evaluate to
|
|
C<ST(1)>.
|
|
|
|
=head2 Default Parameter Values
|
|
|
|
Default values for XSUB arguments can be specified by placing an
|
|
assignment statement in the parameter list. The default value may
|
|
be a number, a string or the special string C<NO_INIT>. Defaults should
|
|
always be used on the right-most parameters only.
|
|
|
|
To allow the XSUB for rpcb_gettime() to have a default host
|
|
value the parameters to the XSUB could be rearranged. The
|
|
XSUB will then call the real rpcb_gettime() function with
|
|
the parameters in the correct order. This XSUB can be called
|
|
from Perl with either of the following statements:
|
|
|
|
$status = rpcb_gettime( $timep, $host );
|
|
|
|
$status = rpcb_gettime( $timep );
|
|
|
|
The XSUB will look like the code which follows. A CODE:
|
|
block is used to call the real rpcb_gettime() function with
|
|
the parameters in the correct order for that function.
|
|
|
|
bool_t
|
|
rpcb_gettime(timep,host="localhost")
|
|
char *host
|
|
time_t timep = NO_INIT
|
|
CODE:
|
|
RETVAL = rpcb_gettime( host, &timep );
|
|
OUTPUT:
|
|
timep
|
|
RETVAL
|
|
|
|
=head2 The PREINIT: Keyword
|
|
|
|
The PREINIT: keyword allows extra variables to be declared immediately
|
|
before or after the declartions of the parameters from the INPUT: section
|
|
are emitted.
|
|
|
|
If a variable is declared inside a CODE: section it will follow any typemap
|
|
code that is emitted for the input parameters. This may result in the
|
|
declaration ending up after C code, which is C syntax error. Similar
|
|
errors may happen with an explicit C<;>-type or C<+>-type initialization of
|
|
parameters is used (see L<"Initializing Function Parameters">). Declaring
|
|
these variables in an INIT: section will not help.
|
|
|
|
In such cases, to force an additional variable to be declared together
|
|
with declarations of other variables, place the declaration into a
|
|
PREINIT: section. The PREINIT: keyword may be used one or more times
|
|
within an XSUB.
|
|
|
|
The following examples are equivalent, but if the code is using complex
|
|
typemaps then the first example is safer.
|
|
|
|
bool_t
|
|
rpcb_gettime(timep)
|
|
time_t timep = NO_INIT
|
|
PREINIT:
|
|
char *host = "localhost";
|
|
CODE:
|
|
RETVAL = rpcb_gettime( host, &timep );
|
|
OUTPUT:
|
|
timep
|
|
RETVAL
|
|
|
|
For this particular case an INIT: keyword would generate the
|
|
same C code as the PREINIT: keyword. Another correct, but error-prone example:
|
|
|
|
bool_t
|
|
rpcb_gettime(timep)
|
|
time_t timep = NO_INIT
|
|
CODE:
|
|
char *host = "localhost";
|
|
RETVAL = rpcb_gettime( host, &timep );
|
|
OUTPUT:
|
|
timep
|
|
RETVAL
|
|
|
|
Another way to declare C<host> is to use a C block in the CODE: section:
|
|
|
|
bool_t
|
|
rpcb_gettime(timep)
|
|
time_t timep = NO_INIT
|
|
CODE:
|
|
{
|
|
char *host = "localhost";
|
|
RETVAL = rpcb_gettime( host, &timep );
|
|
}
|
|
OUTPUT:
|
|
timep
|
|
RETVAL
|
|
|
|
The ability to put additional declarations before the typemap entries are
|
|
processed is very handy in the cases when typemap conversions manipulate
|
|
some global state:
|
|
|
|
MyObject
|
|
mutate(o)
|
|
PREINIT:
|
|
MyState st = global_state;
|
|
INPUT:
|
|
MyObject o;
|
|
CLEANUP:
|
|
reset_to(global_state, st);
|
|
|
|
Here we suppose that conversion to C<MyObject> in the INPUT: section and from
|
|
MyObject when processing RETVAL will modify a global variable C<global_state>.
|
|
After these conversions are performed, we restore the old value of
|
|
C<global_state> (to avoid memory leaks, for example).
|
|
|
|
There is another way to trade clarity for compactness: INPUT sections allow
|
|
declaration of C variables which do not appear in the parameter list of
|
|
a subroutine. Thus the above code for mutate() can be rewritten as
|
|
|
|
MyObject
|
|
mutate(o)
|
|
MyState st = global_state;
|
|
MyObject o;
|
|
CLEANUP:
|
|
reset_to(global_state, st);
|
|
|
|
and the code for rpcb_gettime() can be rewritten as
|
|
|
|
bool_t
|
|
rpcb_gettime(timep)
|
|
time_t timep = NO_INIT
|
|
char *host = "localhost";
|
|
C_ARGS:
|
|
host, &timep
|
|
OUTPUT:
|
|
timep
|
|
RETVAL
|
|
|
|
=head2 The SCOPE: Keyword
|
|
|
|
The SCOPE: keyword allows scoping to be enabled for a particular XSUB. If
|
|
enabled, the XSUB will invoke ENTER and LEAVE automatically.
|
|
|
|
To support potentially complex type mappings, if a typemap entry used
|
|
by an XSUB contains a comment like C</*scope*/> then scoping will
|
|
be automatically enabled for that XSUB.
|
|
|
|
To enable scoping:
|
|
|
|
SCOPE: ENABLE
|
|
|
|
To disable scoping:
|
|
|
|
SCOPE: DISABLE
|
|
|
|
=head2 The INPUT: Keyword
|
|
|
|
The XSUB's parameters are usually evaluated immediately after entering the
|
|
XSUB. The INPUT: keyword can be used to force those parameters to be
|
|
evaluated a little later. The INPUT: keyword can be used multiple times
|
|
within an XSUB and can be used to list one or more input variables. This
|
|
keyword is used with the PREINIT: keyword.
|
|
|
|
The following example shows how the input parameter C<timep> can be
|
|
evaluated late, after a PREINIT.
|
|
|
|
bool_t
|
|
rpcb_gettime(host,timep)
|
|
char *host
|
|
PREINIT:
|
|
time_t tt;
|
|
INPUT:
|
|
time_t timep
|
|
CODE:
|
|
RETVAL = rpcb_gettime( host, &tt );
|
|
timep = tt;
|
|
OUTPUT:
|
|
timep
|
|
RETVAL
|
|
|
|
The next example shows each input parameter evaluated late.
|
|
|
|
bool_t
|
|
rpcb_gettime(host,timep)
|
|
PREINIT:
|
|
time_t tt;
|
|
INPUT:
|
|
char *host
|
|
PREINIT:
|
|
char *h;
|
|
INPUT:
|
|
time_t timep
|
|
CODE:
|
|
h = host;
|
|
RETVAL = rpcb_gettime( h, &tt );
|
|
timep = tt;
|
|
OUTPUT:
|
|
timep
|
|
RETVAL
|
|
|
|
Since INPUT sections allow declaration of C variables which do not appear
|
|
in the parameter list of a subroutine, this may be shortened to:
|
|
|
|
bool_t
|
|
rpcb_gettime(host,timep)
|
|
time_t tt;
|
|
char *host;
|
|
char *h = host;
|
|
time_t timep;
|
|
CODE:
|
|
RETVAL = rpcb_gettime( h, &tt );
|
|
timep = tt;
|
|
OUTPUT:
|
|
timep
|
|
RETVAL
|
|
|
|
(We used our knowledge that input conversion for C<char *> is a "simple" one,
|
|
thus C<host> is initialized on the declaration line, and our assignment
|
|
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 Variable-length Parameter Lists
|
|
|
|
XSUBs can have variable-length parameter lists by specifying an ellipsis
|
|
C<(...)> in the parameter list. This use of the ellipsis is similar to that
|
|
found in ANSI C. The programmer is able to determine the number of
|
|
arguments passed to the XSUB by examining the C<items> variable which the
|
|
B<xsubpp> compiler supplies for all XSUBs. By using this mechanism one can
|
|
create an XSUB which accepts a list of parameters of unknown length.
|
|
|
|
The I<host> parameter for the rpcb_gettime() XSUB can be
|
|
optional so the ellipsis can be used to indicate that the
|
|
XSUB will take a variable number of parameters. Perl should
|
|
be able to call this XSUB with either of the following statements.
|
|
|
|
$status = rpcb_gettime( $timep, $host );
|
|
|
|
$status = rpcb_gettime( $timep );
|
|
|
|
The XS code, with ellipsis, follows.
|
|
|
|
bool_t
|
|
rpcb_gettime(timep, ...)
|
|
time_t timep = NO_INIT
|
|
PREINIT:
|
|
char *host = "localhost";
|
|
STRLEN n_a;
|
|
CODE:
|
|
if( items > 1 )
|
|
host = (char *)SvPV(ST(1), n_a);
|
|
RETVAL = rpcb_gettime( host, &timep );
|
|
OUTPUT:
|
|
timep
|
|
RETVAL
|
|
|
|
=head2 The C_ARGS: Keyword
|
|
|
|
The C_ARGS: keyword allows creating of XSUBS which have different
|
|
calling sequence from Perl than from C, without a need to write
|
|
CODE: or PPCODE: section. The contents of the C_ARGS: paragraph is
|
|
put as the argument to the called C function without any change.
|
|
|
|
For example, suppose that a C function is declared as
|
|
|
|
symbolic nth_derivative(int n, symbolic function, int flags);
|
|
|
|
and that the default flags are kept in a global C variable
|
|
C<default_flags>. Suppose that you want to create an interface which
|
|
is called as
|
|
|
|
$second_deriv = $function->nth_derivative(2);
|
|
|
|
To do this, declare the XSUB as
|
|
|
|
symbolic
|
|
nth_derivative(function, n)
|
|
symbolic function
|
|
int n
|
|
C_ARGS:
|
|
n, function, default_flags
|
|
|
|
=head2 The PPCODE: Keyword
|
|
|
|
The PPCODE: keyword is an alternate form of the CODE: keyword and is used
|
|
to tell the B<xsubpp> compiler that the programmer is supplying the code to
|
|
control the argument stack for the XSUBs return values. Occasionally one
|
|
will want an XSUB to return a list of values rather than a single value.
|
|
In these cases one must use PPCODE: and then explicitly push the list of
|
|
values on the stack. The PPCODE: and CODE: keywords should not be used
|
|
together within the same XSUB.
|
|
|
|
The actual difference between PPCODE: and CODE: sections is in the
|
|
initialization of C<SP> macro (which stands for the I<current> Perl
|
|
stack pointer), and in the handling of data on the stack when returning
|
|
from an XSUB. In CODE: sections SP preserves the value which was on
|
|
entry to the XSUB: SP is on the function pointer (which follows the
|
|
last parameter). In PPCODE: sections SP is moved backward to the
|
|
beginning of the parameter list, which allows C<PUSH*()> macros
|
|
to place output values in the place Perl expects them to be when
|
|
the XSUB returns back to Perl.
|
|
|
|
The generated trailer for a CODE: section ensures that the number of return
|
|
values Perl will see is either 0 or 1 (depending on the C<void>ness of the
|
|
return value of the C function, and heuristics mentioned in
|
|
L<"The RETVAL Variable">). The trailer generated for a PPCODE: section
|
|
is based on the number of return values and on the number of times
|
|
C<SP> was updated by C<[X]PUSH*()> macros.
|
|
|
|
Note that macros C<ST(i)>, C<XST_m*()> and C<XSRETURN*()> work equally
|
|
well in CODE: sections and PPCODE: sections.
|
|
|
|
The following XSUB will call the C rpcb_gettime() function
|
|
and will return its two output values, timep and status, to
|
|
Perl as a single list.
|
|
|
|
void
|
|
rpcb_gettime(host)
|
|
char *host
|
|
PREINIT:
|
|
time_t timep;
|
|
bool_t status;
|
|
PPCODE:
|
|
status = rpcb_gettime( host, &timep );
|
|
EXTEND(SP, 2);
|
|
PUSHs(sv_2mortal(newSViv(status)));
|
|
PUSHs(sv_2mortal(newSViv(timep)));
|
|
|
|
Notice that the programmer must supply the C code necessary
|
|
to have the real rpcb_gettime() function called and to have
|
|
the return values properly placed on the argument stack.
|
|
|
|
The C<void> return type for this function tells the B<xsubpp> compiler that
|
|
the RETVAL variable is not needed or used and that it should not be created.
|
|
In most scenarios the void return type should be used with the PPCODE:
|
|
directive.
|
|
|
|
The EXTEND() macro is used to make room on the argument
|
|
stack for 2 return values. The PPCODE: directive causes the
|
|
B<xsubpp> compiler to create a stack pointer available as C<SP>, and it
|
|
is this pointer which is being used in the EXTEND() macro.
|
|
The values are then pushed onto the stack with the PUSHs()
|
|
macro.
|
|
|
|
Now the rpcb_gettime() function can be used from Perl with
|
|
the following statement.
|
|
|
|
($status, $timep) = rpcb_gettime("localhost");
|
|
|
|
When handling output parameters with a PPCODE section, be sure to handle
|
|
'set' magic properly. See L<perlguts> for details about 'set' magic.
|
|
|
|
=head2 Returning Undef And Empty Lists
|
|
|
|
Occasionally the programmer will want to return simply
|
|
C<undef> or an empty list if a function fails rather than a
|
|
separate status value. The rpcb_gettime() function offers
|
|
just this situation. If the function succeeds we would like
|
|
to have it return the time and if it fails we would like to
|
|
have undef returned. In the following Perl code the value
|
|
of $timep will either be undef or it will be a valid time.
|
|
|
|
$timep = rpcb_gettime( "localhost" );
|
|
|
|
The following XSUB uses the C<SV *> return type as a mnemonic only,
|
|
and uses a CODE: block to indicate to the compiler
|
|
that the programmer has supplied all the necessary code. The
|
|
sv_newmortal() call will initialize the return value to undef, making that
|
|
the default return value.
|
|
|
|
SV *
|
|
rpcb_gettime(host)
|
|
char * host
|
|
PREINIT:
|
|
time_t timep;
|
|
bool_t x;
|
|
CODE:
|
|
ST(0) = sv_newmortal();
|
|
if( rpcb_gettime( host, &timep ) )
|
|
sv_setnv( ST(0), (double)timep);
|
|
|
|
The next example demonstrates how one would place an explicit undef in the
|
|
return value, should the need arise.
|
|
|
|
SV *
|
|
rpcb_gettime(host)
|
|
char * host
|
|
PREINIT:
|
|
time_t timep;
|
|
bool_t x;
|
|
CODE:
|
|
ST(0) = sv_newmortal();
|
|
if( rpcb_gettime( host, &timep ) ){
|
|
sv_setnv( ST(0), (double)timep);
|
|
}
|
|
else{
|
|
ST(0) = &PL_sv_undef;
|
|
}
|
|
|
|
To return an empty list one must use a PPCODE: block and
|
|
then not push return values on the stack.
|
|
|
|
void
|
|
rpcb_gettime(host)
|
|
char *host
|
|
PREINIT:
|
|
time_t timep;
|
|
PPCODE:
|
|
if( rpcb_gettime( host, &timep ) )
|
|
PUSHs(sv_2mortal(newSViv(timep)));
|
|
else{
|
|
/* Nothing pushed on stack, so an empty
|
|
* list is implicitly returned. */
|
|
}
|
|
|
|
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.
|
|
|
|
Since C<XSRETURN_*> macros can be used with CODE blocks as well, one can
|
|
rewrite this example as:
|
|
|
|
int
|
|
rpcb_gettime(host)
|
|
char *host
|
|
PREINIT:
|
|
time_t timep;
|
|
CODE:
|
|
RETVAL = rpcb_gettime( host, &timep );
|
|
if (RETVAL == 0)
|
|
XSRETURN_UNDEF;
|
|
OUTPUT:
|
|
RETVAL
|
|
|
|
In fact, one can put this check into a CLEANUP: section as well. Together
|
|
with PREINIT: simplifications, this leads to:
|
|
|
|
int
|
|
rpcb_gettime(host)
|
|
char *host
|
|
time_t timep;
|
|
CLEANUP:
|
|
if (RETVAL == 0)
|
|
XSRETURN_UNDEF;
|
|
|
|
=head2 The REQUIRE: Keyword
|
|
|
|
The REQUIRE: keyword is used to indicate the minimum version of the
|
|
B<xsubpp> compiler needed to compile the XS module. An XS module which
|
|
contains the following statement will compile with only B<xsubpp> version
|
|
1.922 or greater:
|
|
|
|
REQUIRE: 1.922
|
|
|
|
=head2 The CLEANUP: Keyword
|
|
|
|
This keyword can be used when an XSUB requires special cleanup procedures
|
|
before it terminates. When the CLEANUP: keyword is used it must follow
|
|
any CODE:, PPCODE:, or OUTPUT: blocks which are present in the XSUB. The
|
|
code specified for the cleanup block will be added as the last statements
|
|
in the XSUB.
|
|
|
|
=head2 The BOOT: Keyword
|
|
|
|
The BOOT: keyword is used to add code to the extension's bootstrap
|
|
function. The bootstrap function is generated by the B<xsubpp> compiler and
|
|
normally holds the statements necessary to register any XSUBs with Perl.
|
|
With the BOOT: keyword the programmer can tell the compiler to add extra
|
|
statements to the bootstrap function.
|
|
|
|
This keyword may be used any time after the first MODULE keyword and should
|
|
appear on a line by itself. The first blank line after the keyword will
|
|
terminate the code block.
|
|
|
|
BOOT:
|
|
# The following message will be printed when the
|
|
# bootstrap function executes.
|
|
printf("Hello from the bootstrap!\n");
|
|
|
|
=head2 The VERSIONCHECK: Keyword
|
|
|
|
The VERSIONCHECK: keyword corresponds to B<xsubpp>'s C<-versioncheck> and
|
|
C<-noversioncheck> options. This keyword overrides the command line
|
|
options. Version checking is enabled by default. When version checking is
|
|
enabled the XS module will attempt to verify that its version matches the
|
|
version of the PM module.
|
|
|
|
To enable version checking:
|
|
|
|
VERSIONCHECK: ENABLE
|
|
|
|
To disable version checking:
|
|
|
|
VERSIONCHECK: DISABLE
|
|
|
|
=head2 The PROTOTYPES: Keyword
|
|
|
|
The PROTOTYPES: keyword corresponds to B<xsubpp>'s C<-prototypes> and
|
|
C<-noprototypes> options. This keyword overrides the command line options.
|
|
Prototypes are enabled by default. When prototypes are enabled XSUBs will
|
|
be given Perl prototypes. This keyword may be used multiple times in an XS
|
|
module to enable and disable prototypes for different parts of the module.
|
|
|
|
To enable prototypes:
|
|
|
|
PROTOTYPES: ENABLE
|
|
|
|
To disable prototypes:
|
|
|
|
PROTOTYPES: DISABLE
|
|
|
|
=head2 The PROTOTYPE: Keyword
|
|
|
|
This keyword is similar to the PROTOTYPES: keyword above but can be used to
|
|
force B<xsubpp> to use a specific prototype for the XSUB. This keyword
|
|
overrides all other prototype options and keywords but affects only the
|
|
current XSUB. Consult L<perlsub/Prototypes> for information about Perl
|
|
prototypes.
|
|
|
|
bool_t
|
|
rpcb_gettime(timep, ...)
|
|
time_t timep = NO_INIT
|
|
PROTOTYPE: $;$
|
|
PREINIT:
|
|
char *host = "localhost";
|
|
STRLEN n_a;
|
|
CODE:
|
|
if( items > 1 )
|
|
host = (char *)SvPV(ST(1), n_a);
|
|
RETVAL = rpcb_gettime( host, &timep );
|
|
OUTPUT:
|
|
timep
|
|
RETVAL
|
|
|
|
=head2 The ALIAS: Keyword
|
|
|
|
The ALIAS: keyword allows an XSUB to have two or more unique Perl names
|
|
and to know which of those names was used when it was invoked. The Perl
|
|
names may be fully-qualified with package names. Each alias is given an
|
|
index. The compiler will setup a variable called C<ix> which contain the
|
|
index of the alias which was used. When the XSUB is called with its
|
|
declared name C<ix> will be 0.
|
|
|
|
The following example will create aliases C<FOO::gettime()> and
|
|
C<BAR::getit()> for this function.
|
|
|
|
bool_t
|
|
rpcb_gettime(host,timep)
|
|
char *host
|
|
time_t &timep
|
|
ALIAS:
|
|
FOO::gettime = 1
|
|
BAR::getit = 2
|
|
INIT:
|
|
printf("# ix = %d\n", ix );
|
|
OUTPUT:
|
|
timep
|
|
|
|
=head2 The INTERFACE: Keyword
|
|
|
|
This keyword declares the current XSUB as a keeper of the given
|
|
calling signature. If some text follows this keyword, it is
|
|
considered as a list of functions which have this signature, and
|
|
should be attached to the current XSUB.
|
|
|
|
For example, if you have 4 C functions multiply(), divide(), add(),
|
|
subtract() all having the signature:
|
|
|
|
symbolic f(symbolic, symbolic);
|
|
|
|
you can make them all to use the same XSUB using this:
|
|
|
|
symbolic
|
|
interface_s_ss(arg1, arg2)
|
|
symbolic arg1
|
|
symbolic arg2
|
|
INTERFACE:
|
|
multiply divide
|
|
add subtract
|
|
|
|
(This is the complete XSUB code for 4 Perl functions!) Four generated
|
|
Perl function share names with corresponding C functions.
|
|
|
|
The advantage of this approach comparing to ALIAS: keyword is that there
|
|
is no need to code a switch statement, each Perl function (which shares
|
|
the same XSUB) knows which C function it should call. Additionally, one
|
|
can attach an extra function remainder() at runtime by using
|
|
|
|
CV *mycv = newXSproto("Symbolic::remainder",
|
|
XS_Symbolic_interface_s_ss, __FILE__, "$$");
|
|
XSINTERFACE_FUNC_SET(mycv, remainder);
|
|
|
|
say, from another XSUB. (This example supposes that there was no
|
|
INTERFACE_MACRO: section, otherwise one needs to use something else instead of
|
|
C<XSINTERFACE_FUNC_SET>, see the next section.)
|
|
|
|
=head2 The INTERFACE_MACRO: Keyword
|
|
|
|
This keyword allows one to define an INTERFACE using a different way
|
|
to extract a function pointer from an XSUB. The text which follows
|
|
this keyword should give the name of macros which would extract/set a
|
|
function pointer. The extractor macro is given return type, C<CV*>,
|
|
and C<XSANY.any_dptr> for this C<CV*>. The setter macro is given cv,
|
|
and the function pointer.
|
|
|
|
The default value is C<XSINTERFACE_FUNC> and C<XSINTERFACE_FUNC_SET>.
|
|
An INTERFACE keyword with an empty list of functions can be omitted if
|
|
INTERFACE_MACRO keyword is used.
|
|
|
|
Suppose that in the previous example functions pointers for
|
|
multiply(), divide(), add(), subtract() are kept in a global C array
|
|
C<fp[]> with offsets being C<multiply_off>, C<divide_off>, C<add_off>,
|
|
C<subtract_off>. Then one can use
|
|
|
|
#define XSINTERFACE_FUNC_BYOFFSET(ret,cv,f) \
|
|
((XSINTERFACE_CVT(ret,))fp[CvXSUBANY(cv).any_i32])
|
|
#define XSINTERFACE_FUNC_BYOFFSET_set(cv,f) \
|
|
CvXSUBANY(cv).any_i32 = CAT2( f, _off )
|
|
|
|
in C section,
|
|
|
|
symbolic
|
|
interface_s_ss(arg1, arg2)
|
|
symbolic arg1
|
|
symbolic arg2
|
|
INTERFACE_MACRO:
|
|
XSINTERFACE_FUNC_BYOFFSET
|
|
XSINTERFACE_FUNC_BYOFFSET_set
|
|
INTERFACE:
|
|
multiply divide
|
|
add subtract
|
|
|
|
in XSUB section.
|
|
|
|
=head2 The INCLUDE: Keyword
|
|
|
|
This keyword can be used to pull other files into the XS module. The other
|
|
files may have XS code. INCLUDE: can also be used to run a command to
|
|
generate the XS code to be pulled into the module.
|
|
|
|
The file F<Rpcb1.xsh> contains our C<rpcb_gettime()> function:
|
|
|
|
bool_t
|
|
rpcb_gettime(host,timep)
|
|
char *host
|
|
time_t &timep
|
|
OUTPUT:
|
|
timep
|
|
|
|
The XS module can use INCLUDE: to pull that file into it.
|
|
|
|
INCLUDE: Rpcb1.xsh
|
|
|
|
If the parameters to the INCLUDE: keyword are followed by a pipe (C<|>) then
|
|
the compiler will interpret the parameters as a command.
|
|
|
|
INCLUDE: cat Rpcb1.xsh |
|
|
|
|
=head2 The CASE: Keyword
|
|
|
|
The CASE: keyword allows an XSUB to have multiple distinct parts with each
|
|
part acting as a virtual XSUB. CASE: is greedy and if it is used then all
|
|
other XS keywords must be contained within a CASE:. This means nothing may
|
|
precede the first CASE: in the XSUB and anything following the last CASE: is
|
|
included in that case.
|
|
|
|
A CASE: might switch via a parameter of the XSUB, via the C<ix> ALIAS:
|
|
variable (see L<"The ALIAS: Keyword">), or maybe via the C<items> variable
|
|
(see L<"Variable-length Parameter Lists">). The last CASE: becomes the
|
|
B<default> case if it is not associated with a conditional. The following
|
|
example shows CASE switched via C<ix> with a function C<rpcb_gettime()>
|
|
having an alias C<x_gettime()>. When the function is called as
|
|
C<rpcb_gettime()> its parameters are the usual C<(char *host, time_t *timep)>,
|
|
but when the function is called as C<x_gettime()> its parameters are
|
|
reversed, C<(time_t *timep, char *host)>.
|
|
|
|
long
|
|
rpcb_gettime(a,b)
|
|
CASE: ix == 1
|
|
ALIAS:
|
|
x_gettime = 1
|
|
INPUT:
|
|
# 'a' is timep, 'b' is host
|
|
char *b
|
|
time_t a = NO_INIT
|
|
CODE:
|
|
RETVAL = rpcb_gettime( b, &a );
|
|
OUTPUT:
|
|
a
|
|
RETVAL
|
|
CASE:
|
|
# 'a' is host, 'b' is timep
|
|
char *a
|
|
time_t &b = NO_INIT
|
|
OUTPUT:
|
|
b
|
|
RETVAL
|
|
|
|
That function can be called with either of the following statements. Note
|
|
the different argument lists.
|
|
|
|
$status = rpcb_gettime( $host, $timep );
|
|
|
|
$status = x_gettime( $timep, $host );
|
|
|
|
=head2 The & Unary Operator
|
|
|
|
The C<&> unary operator in the INPUT: section is used to tell B<xsubpp>
|
|
that it should convert a Perl value to/from C using the C type to the left
|
|
of C<&>, but provide a pointer to this value when the C function is called.
|
|
|
|
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*>).
|
|
|
|
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
|
|
*host, time_t timep)>, but the real C<rpcb_gettime()> wants the C<timep>
|
|
parameter to be of type C<time_t*> rather than C<time_t>.
|
|
|
|
bool_t
|
|
rpcb_gettime(host,timep)
|
|
char *host
|
|
time_t timep
|
|
OUTPUT:
|
|
timep
|
|
|
|
That problem is corrected by using the C<&> operator. The B<xsubpp> compiler
|
|
will now turn this into code which calls C<rpcb_gettime()> correctly with
|
|
parameters C<(char *host, time_t *timep)>. It does this by carrying the
|
|
C<&> through, so the function call looks like C<rpcb_gettime(host, &timep)>.
|
|
|
|
bool_t
|
|
rpcb_gettime(host,timep)
|
|
char *host
|
|
time_t &timep
|
|
OUTPUT:
|
|
timep
|
|
|
|
=head2 Inserting Comments and C Preprocessor Directives
|
|
|
|
C preprocessor directives are allowed within BOOT:, PREINIT: INIT:,
|
|
CODE:, PPCODE:, 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.
|
|
|
|
Comments can be added to XSUBs by placing a C<#> as the first
|
|
non-whitespace of a line. Care should be taken to avoid making the
|
|
comment look like a C preprocessor directive, lest it be interpreted as
|
|
such. The simplest way to prevent this is to put whitespace in front of
|
|
the C<#>.
|
|
|
|
If you use preprocessor directives to choose one of two
|
|
versions of a function, use
|
|
|
|
#if ... version1
|
|
#else /* ... version2 */
|
|
#endif
|
|
|
|
and not
|
|
|
|
#if ... version1
|
|
#endif
|
|
#if ... version2
|
|
#endif
|
|
|
|
because otherwise B<xsubpp> will believe that you made a duplicate
|
|
definition of the function. Also, put a blank line before the
|
|
#else/#endif so it will not be seen as part of the function body.
|
|
|
|
=head2 Using XS With C++
|
|
|
|
If an XSUB name contains C<::>, it is considered to be a C++ method.
|
|
The generated Perl function will assume that
|
|
its first argument is an object pointer. The object pointer
|
|
will be stored in a variable called THIS. The object should
|
|
have been created by C++ with the new() function and should
|
|
be blessed by Perl with the sv_setref_pv() macro. The
|
|
blessing of the object by Perl can be handled by a typemap. An example
|
|
typemap is shown at the end of this section.
|
|
|
|
If the return type of the XSUB includes C<static>, the method is considered
|
|
to be a static method. It will call the C++
|
|
function using the class::method() syntax. If the method is not static
|
|
the function will be called using the THIS-E<gt>method() syntax.
|
|
|
|
The next examples will use the following C++ class.
|
|
|
|
class color {
|
|
public:
|
|
color();
|
|
~color();
|
|
int blue();
|
|
void set_blue( int );
|
|
|
|
private:
|
|
int c_blue;
|
|
};
|
|
|
|
The XSUBs for the blue() and set_blue() methods are defined with the class
|
|
name but the parameter for the object (THIS, or "self") is implicit and is
|
|
not listed.
|
|
|
|
int
|
|
color::blue()
|
|
|
|
void
|
|
color::set_blue( val )
|
|
int val
|
|
|
|
Both Perl functions will expect an object as the first parameter. In the
|
|
generated C++ code the object is called C<THIS>, and the method call will
|
|
be performed on this object. So in the C++ code the blue() and set_blue()
|
|
methods will be called as this:
|
|
|
|
RETVAL = THIS->blue();
|
|
|
|
THIS->set_blue( val );
|
|
|
|
You could also write a single get/set method using an optional argument:
|
|
|
|
int
|
|
color::blue( val = NO_INIT )
|
|
int val
|
|
PROTOTYPE $;$
|
|
CODE:
|
|
if (items > 1)
|
|
THIS->set_blue( val );
|
|
RETVAL = THIS->blue();
|
|
OUTPUT:
|
|
RETVAL
|
|
|
|
If the function's name is B<DESTROY> then the C++ C<delete> function will be
|
|
called and C<THIS> will be given as its parameter. The generated C++ code for
|
|
|
|
void
|
|
color::DESTROY()
|
|
|
|
will look like this:
|
|
|
|
color *THIS = ...; // Initialized as in typemap
|
|
|
|
delete THIS;
|
|
|
|
If the function's name is B<new> then the C++ C<new> function will be called
|
|
to create a dynamic C++ object. The XSUB will expect the class name, which
|
|
will be kept in a variable called C<CLASS>, to be given as the first
|
|
argument.
|
|
|
|
color *
|
|
color::new()
|
|
|
|
The generated C++ code will call C<new>.
|
|
|
|
RETVAL = new color();
|
|
|
|
The following is an example of a typemap that could be used for this C++
|
|
example.
|
|
|
|
TYPEMAP
|
|
color * O_OBJECT
|
|
|
|
OUTPUT
|
|
# The Perl object is blessed into 'CLASS', which should be a
|
|
# char* having the name of the package for the blessing.
|
|
O_OBJECT
|
|
sv_setref_pv( $arg, CLASS, (void*)$var );
|
|
|
|
INPUT
|
|
O_OBJECT
|
|
if( sv_isobject($arg) && (SvTYPE(SvRV($arg)) == SVt_PVMG) )
|
|
$var = ($type)SvIV((SV*)SvRV( $arg ));
|
|
else{
|
|
warn( \"${Package}::$func_name() -- $var is not a blessed SV reference\" );
|
|
XSRETURN_UNDEF;
|
|
}
|
|
|
|
=head2 Interface Strategy
|
|
|
|
When designing an interface between Perl and a C library a straight
|
|
translation from C to XS (such as created by C<h2xs -x>) is often sufficient.
|
|
However, sometimes the interface will look
|
|
very C-like and occasionally nonintuitive, especially when the C function
|
|
modifies one of its parameters, or returns failure inband (as in "negative
|
|
return values mean failure"). In cases where the programmer wishes to
|
|
create a more Perl-like interface the following strategy may help to
|
|
identify the more critical parts of the interface.
|
|
|
|
Identify the C functions with input/output or output parameters. The XSUBs for
|
|
these functions may be able to return lists to Perl.
|
|
|
|
Identify the C functions which use some inband info as an indication
|
|
of failure. They may be
|
|
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 CLEANUP: 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,
|
|
you may want to create a special typedef to handle this situation. Put
|
|
|
|
typedef int negative_is_failure;
|
|
|
|
near the beginning of XS file, and create an OUTPUT typemap entry
|
|
for C<negative_is_failure> which converts negative values to C<undef>, or
|
|
maybe croak()s. After this the return value of type C<negative_is_failure>
|
|
will create more Perl-like interface.
|
|
|
|
Identify which values are used by only the C and XSUB functions
|
|
themselves, say, when a parameter to a function should be a contents of a
|
|
global variable. If Perl does not need to access the contents of the value
|
|
then it may not be necessary to provide a translation for that value
|
|
from C to Perl.
|
|
|
|
Identify the pointers in the C function parameter lists and return
|
|
values. Some pointers may be used to implement input/output or
|
|
output parameters, they can be handled in XS with the C<&> unary operator,
|
|
and, possibly, using the NO_INIT keyword.
|
|
Some others will require handling of types like C<int *>, and one needs
|
|
to decide what a useful Perl translation will do in such a case. When
|
|
the semantic is clear, it is advisable to put the translation into a typemap
|
|
file.
|
|
|
|
Identify the structures used by the C functions. In many
|
|
cases it may be helpful to use the T_PTROBJ typemap for
|
|
these structures so they can be manipulated by Perl as
|
|
blessed objects. (This is handled automatically by C<h2xs -x>.)
|
|
|
|
If the same C type is used in several different contexts which require
|
|
different translations, C<typedef> several new types mapped to this C type,
|
|
and create separate F<typemap> entries for these new types. Use these
|
|
types in declarations of return type and parameters to XSUBs.
|
|
|
|
=head2 Perl Objects And C Structures
|
|
|
|
When dealing with C structures one should select either
|
|
B<T_PTROBJ> or B<T_PTRREF> for the XS type. Both types are
|
|
designed to handle pointers to complex objects. The
|
|
T_PTRREF type will allow the Perl object to be unblessed
|
|
while the T_PTROBJ type requires that the object be blessed.
|
|
By using T_PTROBJ one can achieve a form of type-checking
|
|
because the XSUB will attempt to verify that the Perl object
|
|
is of the expected type.
|
|
|
|
The following XS code shows the getnetconfigent() function which is used
|
|
with ONC+ TIRPC. The getnetconfigent() function will return a pointer to a
|
|
C structure and has the C prototype shown below. The example will
|
|
demonstrate how the C pointer will become a Perl reference. Perl will
|
|
consider this reference to be a pointer to a blessed object and will
|
|
attempt to call a destructor for the object. A destructor will be
|
|
provided in the XS source to free the memory used by getnetconfigent().
|
|
Destructors in XS can be created by specifying an XSUB function whose name
|
|
ends with the word B<DESTROY>. XS destructors can be used to free memory
|
|
which may have been malloc'd by another XSUB.
|
|
|
|
struct netconfig *getnetconfigent(const char *netid);
|
|
|
|
A C<typedef> will be created for C<struct netconfig>. The Perl
|
|
object will be blessed in a class matching the name of the C
|
|
type, with the tag C<Ptr> appended, and the name should not
|
|
have embedded spaces if it will be a Perl package name. The
|
|
destructor will be placed in a class corresponding to the
|
|
class of the object and the PREFIX keyword will be used to
|
|
trim the name to the word DESTROY as Perl will expect.
|
|
|
|
typedef struct netconfig Netconfig;
|
|
|
|
MODULE = RPC PACKAGE = RPC
|
|
|
|
Netconfig *
|
|
getnetconfigent(netid)
|
|
char *netid
|
|
|
|
MODULE = RPC PACKAGE = NetconfigPtr PREFIX = rpcb_
|
|
|
|
void
|
|
rpcb_DESTROY(netconf)
|
|
Netconfig *netconf
|
|
CODE:
|
|
printf("Now in NetconfigPtr::DESTROY\n");
|
|
free( netconf );
|
|
|
|
This example requires the following typemap entry. Consult the typemap
|
|
section for more information about adding new typemaps for an extension.
|
|
|
|
TYPEMAP
|
|
Netconfig * T_PTROBJ
|
|
|
|
This example will be used with the following Perl statements.
|
|
|
|
use RPC;
|
|
$netconf = getnetconfigent("udp");
|
|
|
|
When Perl destroys the object referenced by $netconf it will send the
|
|
object to the supplied XSUB DESTROY function. Perl cannot determine, and
|
|
does not care, that this object is a C struct and not a Perl object. In
|
|
this sense, there is no difference between the object created by the
|
|
getnetconfigent() XSUB and an object created by a normal Perl subroutine.
|
|
|
|
=head2 The Typemap
|
|
|
|
The typemap is a collection of code fragments which are used by the B<xsubpp>
|
|
compiler to map C function parameters and values to Perl values. The
|
|
typemap file may consist of three sections labeled C<TYPEMAP>, C<INPUT>, and
|
|
C<OUTPUT>. An unlabelled initial section is assumed to be a C<TYPEMAP>
|
|
section. The INPUT section tells
|
|
the compiler how to translate Perl values
|
|
into variables of certain C types. The OUTPUT section tells the compiler
|
|
how to translate the values from certain C types into values Perl can
|
|
understand. The TYPEMAP section tells the compiler which of the INPUT and
|
|
OUTPUT code fragments should be used to map a given C type to a Perl value.
|
|
The section labels C<TYPEMAP>, C<INPUT>, or C<OUTPUT> must begin
|
|
in the first column on a line by themselves, and must be in uppercase.
|
|
|
|
The default typemap in the C<ext> directory of the Perl source contains many
|
|
useful types which can be used by Perl extensions. Some extensions define
|
|
additional typemaps which they keep in their own directory. These
|
|
additional typemaps may reference INPUT and OUTPUT maps in the main
|
|
typemap. The B<xsubpp> compiler will allow the extension's own typemap to
|
|
override any mappings which are in the default typemap.
|
|
|
|
Most extensions which require a custom typemap will need only the TYPEMAP
|
|
section of the typemap file. The custom typemap used in the
|
|
getnetconfigent() example shown earlier demonstrates what may be the typical
|
|
use of extension typemaps. That typemap is used to equate a C structure
|
|
with the T_PTROBJ typemap. The typemap used by getnetconfigent() is shown
|
|
here. Note that the C type is separated from the XS type with a tab and
|
|
that the C unary operator C<*> is considered to be a part of the C type name.
|
|
|
|
TYPEMAP
|
|
Netconfig *<tab>T_PTROBJ
|
|
|
|
Here's a more complicated example: suppose that you wanted C<struct
|
|
netconfig> to be blessed into the class C<Net::Config>. One way to do
|
|
this is to use underscores (_) to separate package names, as follows:
|
|
|
|
typedef struct netconfig * Net_Config;
|
|
|
|
And then provide a typemap entry C<T_PTROBJ_SPECIAL> that maps underscores to
|
|
double-colons (::), and declare C<Net_Config> to be of that type:
|
|
|
|
|
|
TYPEMAP
|
|
Net_Config T_PTROBJ_SPECIAL
|
|
|
|
INPUT
|
|
T_PTROBJ_SPECIAL
|
|
if (sv_derived_from($arg, \"${(my $ntt=$ntype)=~s/_/::/g;\$ntt}\")) {
|
|
IV tmp = SvIV((SV*)SvRV($arg));
|
|
$var = ($type) tmp;
|
|
}
|
|
else
|
|
croak(\"$var is not of type ${(my $ntt=$ntype)=~s/_/::/g;\$ntt}\")
|
|
|
|
OUTPUT
|
|
T_PTROBJ_SPECIAL
|
|
sv_setref_pv($arg, \"${(my $ntt=$ntype)=~s/_/::/g;\$ntt}\",
|
|
(void*)$var);
|
|
|
|
The INPUT and OUTPUT sections substitute underscores for double-colons
|
|
on the fly, giving the desired effect. This example demonstrates some
|
|
of the power and versatility of the typemap facility.
|
|
|
|
=head1 EXAMPLES
|
|
|
|
File C<RPC.xs>: Interface to some ONC+ RPC bind library functions.
|
|
|
|
#include "EXTERN.h"
|
|
#include "perl.h"
|
|
#include "XSUB.h"
|
|
|
|
#include <rpc/rpc.h>
|
|
|
|
typedef struct netconfig Netconfig;
|
|
|
|
MODULE = RPC PACKAGE = RPC
|
|
|
|
SV *
|
|
rpcb_gettime(host="localhost")
|
|
char *host
|
|
PREINIT:
|
|
time_t timep;
|
|
CODE:
|
|
ST(0) = sv_newmortal();
|
|
if( rpcb_gettime( host, &timep ) )
|
|
sv_setnv( ST(0), (double)timep );
|
|
|
|
Netconfig *
|
|
getnetconfigent(netid="udp")
|
|
char *netid
|
|
|
|
MODULE = RPC PACKAGE = NetconfigPtr PREFIX = rpcb_
|
|
|
|
void
|
|
rpcb_DESTROY(netconf)
|
|
Netconfig *netconf
|
|
CODE:
|
|
printf("NetconfigPtr::DESTROY\n");
|
|
free( netconf );
|
|
|
|
File C<typemap>: Custom typemap for RPC.xs.
|
|
|
|
TYPEMAP
|
|
Netconfig * T_PTROBJ
|
|
|
|
File C<RPC.pm>: Perl module for the RPC extension.
|
|
|
|
package RPC;
|
|
|
|
require Exporter;
|
|
require DynaLoader;
|
|
@ISA = qw(Exporter DynaLoader);
|
|
@EXPORT = qw(rpcb_gettime getnetconfigent);
|
|
|
|
bootstrap RPC;
|
|
1;
|
|
|
|
File C<rpctest.pl>: Perl test program for the RPC extension.
|
|
|
|
use RPC;
|
|
|
|
$netconf = getnetconfigent();
|
|
$a = rpcb_gettime();
|
|
print "time = $a\n";
|
|
print "netconf = $netconf\n";
|
|
|
|
$netconf = getnetconfigent("tcp");
|
|
$a = rpcb_gettime("poplar");
|
|
print "time = $a\n";
|
|
print "netconf = $netconf\n";
|
|
|
|
|
|
=head1 XS VERSION
|
|
|
|
This document covers features supported by C<xsubpp> 1.935.
|
|
|
|
=head1 AUTHOR
|
|
|
|
Originally written by Dean Roehrich <F<roehrich@cray.com>>.
|
|
|
|
Maintained since 1996 by The Perl Porters <F<perlbug@perl.com>>.
|