From c85261a4cef59150c379ff88a21d0f9ca6374dc2 Mon Sep 17 00:00:00 2001 From: Jitka Plesnikova Date: Thu, 24 May 2018 09:57:37 +0200 Subject: [PATCH] Upgrade to 3.39 --- Changes | 6 + lib/ExtUtils/ParseXS.pm | 14 +- lib/ExtUtils/ParseXS/Constants.pm | 2 +- lib/ExtUtils/ParseXS/CountLines.pm | 2 +- lib/ExtUtils/ParseXS/Eval.pm | 6 +- lib/ExtUtils/ParseXS/Utilities.pm | 2 +- lib/ExtUtils/Typemaps.pm | 6 +- lib/ExtUtils/Typemaps/Cmd.pm | 2 +- lib/ExtUtils/Typemaps/InputMap.pm | 2 +- lib/ExtUtils/Typemaps/OutputMap.pm | 2 +- lib/ExtUtils/Typemaps/Type.pm | 2 +- lib/perlxs.pod | 2354 ++++++++++++++++++++++++++++++++++++ lib/perlxstut.pod | 1401 +++++++++++++++++++++ lib/perlxstypemap.pod | 711 +++++++++++ t/XSTest.xs | 1 + t/XSUsage.xs | 2 + 16 files changed, 4497 insertions(+), 18 deletions(-) create mode 100644 lib/perlxs.pod create mode 100644 lib/perlxstut.pod create mode 100644 lib/perlxstypemap.pod diff --git a/Changes b/Changes index 0181371..f9fb36e 100644 --- a/Changes +++ b/Changes @@ -1,5 +1,11 @@ Revision history for Perl extension ExtUtils::ParseXS. +3.36 + - Make generated code avoid warnings about the "items" variable + being unused + - Avoid some unused-variable warnings generated by XS code in the + test suite + 3.35 - Mon Jul 31 17:50:00 CET 2017 - Fix ExtUtils-ParseXS/t/*.t that needed '.' in @INC (David Mitchell) - Remove impediment to compiling under C++11 (Karl Williamson) diff --git a/lib/ExtUtils/ParseXS.pm b/lib/ExtUtils/ParseXS.pm index d629cf6..e1f0940 100644 --- a/lib/ExtUtils/ParseXS.pm +++ b/lib/ExtUtils/ParseXS.pm @@ -11,12 +11,12 @@ use Symbol; our $VERSION; BEGIN { - $VERSION = '3.35'; + $VERSION = '3.39'; + require ExtUtils::ParseXS::Constants; ExtUtils::ParseXS::Constants->VERSION($VERSION); + require ExtUtils::ParseXS::CountLines; ExtUtils::ParseXS::CountLines->VERSION($VERSION); + require ExtUtils::ParseXS::Utilities; ExtUtils::ParseXS::Utilities->VERSION($VERSION); + require ExtUtils::ParseXS::Eval; ExtUtils::ParseXS::Eval->VERSION($VERSION); } -use ExtUtils::ParseXS::Constants $VERSION; -use ExtUtils::ParseXS::CountLines $VERSION; -use ExtUtils::ParseXS::Utilities $VERSION; -use ExtUtils::ParseXS::Eval $VERSION; $VERSION = eval $VERSION if $VERSION =~ /_/; use ExtUtils::ParseXS::Utilities qw( @@ -519,9 +519,10 @@ EOF EOF } else { - # cv likely to be unused + # cv and items likely to be unused print Q(<<"EOF"); # PERL_UNUSED_VAR(cv); /* -W */ +# PERL_UNUSED_VAR(items); /* -W */ EOF } @@ -871,6 +872,7 @@ EOF #XS_EUPXS(XS_$self->{Packid}_nil) #{ # dXSARGS; +# PERL_UNUSED_VAR(items); # XSRETURN_EMPTY; #} # diff --git a/lib/ExtUtils/ParseXS/Constants.pm b/lib/ExtUtils/ParseXS/Constants.pm index 2150fb8..45b5674 100644 --- a/lib/ExtUtils/ParseXS/Constants.pm +++ b/lib/ExtUtils/ParseXS/Constants.pm @@ -3,7 +3,7 @@ use strict; use warnings; use Symbol; -our $VERSION = '3.35'; +our $VERSION = '3.39'; =head1 NAME diff --git a/lib/ExtUtils/ParseXS/CountLines.pm b/lib/ExtUtils/ParseXS/CountLines.pm index ad86b57..5b48449 100644 --- a/lib/ExtUtils/ParseXS/CountLines.pm +++ b/lib/ExtUtils/ParseXS/CountLines.pm @@ -1,7 +1,7 @@ package ExtUtils::ParseXS::CountLines; use strict; -our $VERSION = '3.35'; +our $VERSION = '3.39'; our $SECTION_END_MARKER; diff --git a/lib/ExtUtils/ParseXS/Eval.pm b/lib/ExtUtils/ParseXS/Eval.pm index 6b06bf5..9eba5e5 100644 --- a/lib/ExtUtils/ParseXS/Eval.pm +++ b/lib/ExtUtils/ParseXS/Eval.pm @@ -2,7 +2,7 @@ package ExtUtils::ParseXS::Eval; use strict; use warnings; -our $VERSION = '3.35'; +our $VERSION = '3.39'; =head1 NAME @@ -29,7 +29,7 @@ Warns the contents of C<$@> if any. Not all these variables are necessarily considered "public" wrt. use in typemaps, so beware. Variables set up from the ExtUtils::ParseXS object: - $Package $Alias $func_name $Full_func_name $pname + $Package $ALIAS $func_name $Full_func_name $pname Variables set up from C<$other_hashref>: @@ -63,7 +63,7 @@ Warns the contents of C<$@> if any. Not all these variables are necessarily considered "public" wrt. use in typemaps, so beware. Variables set up from the ExtUtils::ParseXS object: - $Package $Alias $func_name $Full_func_name $pname + $Package $ALIAS $func_name $Full_func_name $pname Variables set up from C<$other_hashref>: diff --git a/lib/ExtUtils/ParseXS/Utilities.pm b/lib/ExtUtils/ParseXS/Utilities.pm index bc1e098..ae25b33 100644 --- a/lib/ExtUtils/ParseXS/Utilities.pm +++ b/lib/ExtUtils/ParseXS/Utilities.pm @@ -5,7 +5,7 @@ use Exporter; use File::Spec; use ExtUtils::ParseXS::Constants (); -our $VERSION = '3.35'; +our $VERSION = '3.39'; our (@ISA, @EXPORT_OK); @ISA = qw(Exporter); diff --git a/lib/ExtUtils/Typemaps.pm b/lib/ExtUtils/Typemaps.pm index 992d15b..a762322 100644 --- a/lib/ExtUtils/Typemaps.pm +++ b/lib/ExtUtils/Typemaps.pm @@ -2,7 +2,7 @@ package ExtUtils::Typemaps; use 5.006001; use strict; use warnings; -our $VERSION = '3.35'; +our $VERSION = '3.38'; require ExtUtils::ParseXS; require ExtUtils::ParseXS::Constants; @@ -781,7 +781,9 @@ corresponding OUTPUT code: $var.context.value().size()); ', 'T_OUT' => ' { - GV *gv = newGVgen("$Package"); + GV *gv = (GV *)sv_newmortal(); + gv_init_pvn(gv, gv_stashpvs("$Package",1), + "__ANONIO__",10,0); if ( do_open(gv, "+>&", 3, FALSE, 0, 0, $var) ) sv_setsv( $arg, diff --git a/lib/ExtUtils/Typemaps/Cmd.pm b/lib/ExtUtils/Typemaps/Cmd.pm index 7ff0780..3c33f54 100644 --- a/lib/ExtUtils/Typemaps/Cmd.pm +++ b/lib/ExtUtils/Typemaps/Cmd.pm @@ -2,7 +2,7 @@ package ExtUtils::Typemaps::Cmd; use 5.006001; use strict; use warnings; -our $VERSION = '3.35'; +our $VERSION = '3.38'; use ExtUtils::Typemaps; diff --git a/lib/ExtUtils/Typemaps/InputMap.pm b/lib/ExtUtils/Typemaps/InputMap.pm index b626973..bf19df1 100644 --- a/lib/ExtUtils/Typemaps/InputMap.pm +++ b/lib/ExtUtils/Typemaps/InputMap.pm @@ -2,7 +2,7 @@ package ExtUtils::Typemaps::InputMap; use 5.006001; use strict; use warnings; -our $VERSION = '3.35'; +our $VERSION = '3.38'; =head1 NAME diff --git a/lib/ExtUtils/Typemaps/OutputMap.pm b/lib/ExtUtils/Typemaps/OutputMap.pm index 8c72e5b..90adb48 100644 --- a/lib/ExtUtils/Typemaps/OutputMap.pm +++ b/lib/ExtUtils/Typemaps/OutputMap.pm @@ -2,7 +2,7 @@ package ExtUtils::Typemaps::OutputMap; use 5.006001; use strict; use warnings; -our $VERSION = '3.35'; +our $VERSION = '3.38'; =head1 NAME diff --git a/lib/ExtUtils/Typemaps/Type.pm b/lib/ExtUtils/Typemaps/Type.pm index 7909bbe..01bd51d 100644 --- a/lib/ExtUtils/Typemaps/Type.pm +++ b/lib/ExtUtils/Typemaps/Type.pm @@ -4,7 +4,7 @@ use strict; use warnings; require ExtUtils::Typemaps; -our $VERSION = '3.35'; +our $VERSION = '3.38'; =head1 NAME diff --git a/lib/perlxs.pod b/lib/perlxs.pod new file mode 100644 index 0000000..1419ee0 --- /dev/null +++ b/lib/perlxs.pod @@ -0,0 +1,2354 @@ +=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. + +Before writing XS, read the L section below. + +An B forms the basic unit of the XS interface. After compilation +by the B 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 of what should be done by +the glue, and let the XS compiler B 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 +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. 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 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. For more information on typemaps, +see L. + +A file in XS format starts with a C language section which goes until the +first C> 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. B recognizes and +skips POD (see L) in both the C and XS language sections, which +allows the XS file to contain embedded documentation. + +See L 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 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 + 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, C, and C, will always be present at the +beginning of an XS file. This approach and others will be +expanded later in this document. A #define for C +should be present to fetch the interpreter context more efficiently, +see L for details. + + #define PERL_NO_GET_CONTEXT + #include "EXTERN.h" + #include "perl.h" + #include "XSUB.h" + #include + + 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 +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 + +Optionally, one can merge the description of types and the list of +argument names, rewriting this as + + double + sin(double x) + +This makes this XSUB look similar to an ANSI C declaration. An optional +semicolon is allowed after the argument list, as in + + double + sin(double x); + +Parameters with C pointer types can have different semantic: C functions +with similar declarations + + bool string_looks_as_a_number(char *s); + bool make_char_uppercase(char *c); + +are used in absolutely incompatible manner. Parameters to these functions +could be described B like this: + + char * s + char &c + +Both these XS declarations correspond to the C C type, but they have +different semantics, see L<"The & Unary Operator">. + +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 +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 rest of the function description 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.) + +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, where I +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 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 compiler will declare this variable in each XSUB +with non-C 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 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 return value should be used +only for subroutines which do not return a value, I CODE: +directive is used which sets ST(0) explicitly. + +Older versions of this document recommended to use C return +value in such cases. It was discovered that this could lead to +segfaults in cases when XSUB was I C. This practice is +now deprecated, and may be not supported at some future version. Use +the return value C in such cases. (Currently C 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 as return value.) + +=head2 Returning SVs, AVs and HVs through RETVAL + +When you're using RETVAL to return an C, 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.) To make your life +easier, the typemap file automatically makes C mortal when +you're returning an C. 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, it's unfortunately not as easy +to have C or C as a return value. You I 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 +is not properly decremented. Thus, the above XSUB would leak memory +whenever it is being called. The same problem exists for C, +C, and C (which indicates a scalar reference, not +a general C). +In XS code on perls starting with perl 5.16, you can override the +typemaps for any of these types with a version that has proper +handling of refcounts. In your C section, do + + AV* T_AVREF_REFCOUNT_FIXED + +to get the repaired variant. For backward compatibility with older +versions of perl, you can instead decrement the reference count +manually when you're returning one of the aforementioned +types using C: + + AV * + array() + CODE: + RETVAL = newAV(); + sv_2mortal((SV*)RETVAL); + /* do something with RETVAL */ + OUTPUT: + RETVAL + +Remember that you don't have to do this for an C. The reference +documentation for all core typemaps can be found in L. + +=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 with +POD stripped, but otherwise 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 ] + +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. + +=head2 The PREFIX Keyword + +The PREFIX keyword designates prefixes which should be +removed from the Perl function names. If the C function is +C and the PREFIX value is C then Perl will +see this function as C. + +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 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 emits an automatic C 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 line +to disable it for the remainder of the parameters in the OUTPUT section. +Likewise, C can be used to reenable it for the +remainder of the OUTPUT section. See L for more details +about 'set' magic. + +=head2 The NO_OUTPUT Keyword + +The NO_OUTPUT can be placed as the first token of the XSUB. This keyword +indicates that while the C subroutine we provide an interface to has +a non-C return type, the return value of this C subroutine should not +be returned from the generated Perl subroutine. + +With this keyword present L is created, and in the +generated call to the subroutine this variable is assigned to, but the value +of this variable is not going to be used in the auto-generated code. + +This keyword makes sense only if C is going to be accessed by the +user-supplied code. It is especially useful to make a function interface +more Perl-like, especially when the C return value is just an error condition +indicator. For example, + + NO_OUTPUT int + delete_file(char *name) + POSTCALL: + if (RETVAL != 0) + croak("Error %d while deleting file '%s'", RETVAL, name); + +Here the generated XS function returns nothing on success, and will die() +with a meaningful error message on error. + +=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 +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 The TYPEMAP: Keyword + +Starting with Perl 5.16, you can embed typemaps into your XS code +instead of or in addition to typemaps in a separate file. Multiple +such embedded typemaps will be processed in order of appearance in +the XS code and like local typemap files take precedence over the +default typemap, the embedded typemaps may overwrite previous +definitions of TYPEMAP, INPUT, and OUTPUT stanzas. The syntax for +embedded typemaps is + + TYPEMAP: < keyword must appear in the first column of a +new line. + +Refer to L for details on writing typemaps. + +=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'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 C<$var>, C<$arg>, +and C<$type> can be used as in typemaps. + + bool_t + rpcb_gettime(host,timep) + char *host = (char *)SvPV_nolen($arg); + 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_nolen($arg) : 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, 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 line, +C<$arg> will evaluate to C, and C<$v{timep}> will evaluate to +C. + +=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. 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 declarations 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 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 in the INPUT: section and from +MyObject when processing RETVAL will modify a global variable C. +After these conversions are performed, we restore the old value of +C (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 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 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 is a "simple" one, +thus C is initialized on the declaration line, and our assignment +C is not performed too early. Otherwise one would need to have the +assignment C in a CODE: or INIT: section.) + +=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/C/C/C/C keywords. +C keyword is the default, the other keywords indicate how the Perl +interface should differ from the C interface. + +Parameters preceded by C/C/C/C +keywords are considered to be used by the C subroutine I. C/C 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 keyword do not appear in the usage +signature of the generated Perl function. + +Parameters preceded by C/C/C I appear as +parameters to the Perl function. With the exception of +C-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 return type or +C was used) followed by all the C +and C parameters (in the order of appearance). On the +return from the XSUB the C/C 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) + int day + int unix_time + int month + +should be used from Perl as + + my ($day, $month) = day_month(time); + +The C signature of the corresponding function should be + + void day_month(int *day, int unix_time, int *month); + +The C/C/C/C/C 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 keyword is omitted). + +The C parameters are identical with parameters introduced with +L and put into the C section (see +L). The C 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/C parameter differ from C/C +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) + int &day = NO_INIT + int unix_time + int &month = NO_INIT + OUTPUT: + day + month + +However, the generated Perl function is called in very C-ish style: + + my ($day, $month); + day_month($day, time, $month); + +=head2 The C Keyword + +If one of the input arguments to the C function is the length of a string +argument C, one can substitute the name of the length-argument by +C 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. + +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 +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 variable which the +B 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 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"; + CODE: + if( items > 1 ) + host = (char *)SvPV_nolen(ST(1)); + 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. 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 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 macro (which stands for the I 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 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 Cness 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 was updated by C<[X]PUSH*()> macros. + +Note that macros C, C and C 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 return type for this function tells the B 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 compiler to create a stack pointer available as C, 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 for details about 'set' magic. + +=head2 Returning Undef And Empty Lists + +Occasionally the programmer will want to return simply +C 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 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: + if( rpcb_gettime( host, &timep ) ){ + ST(0) = sv_newmortal(); + 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 in the above +XSUB, rather than letting control fall through to the end. In those +situations C should be used, instead. This will ensure that +the XSUB stack is properly adjusted. Consult L for other +C macros. + +Since C 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 POSTCALL: section as well. Together +with PREINIT: simplifications, this leads to: + + int + rpcb_gettime(host) + char *host + time_t timep; + POSTCALL: + if (RETVAL == 0) + XSRETURN_UNDEF; + +=head2 The REQUIRE: Keyword + +The REQUIRE: keyword is used to indicate the minimum version of the +B compiler needed to compile the XS module. An XS module which +contains the following statement will compile with only B 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:, 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 POSTCALL: Keyword + +This keyword can be used when an XSUB requires special procedures +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. + +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 + +The BOOT: keyword is used to add code to the extension's bootstrap +function. The bootstrap function is generated by the B 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'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 + +Note that if the version of the PM module is an NV (a floating point +number), it will be stringified with a possible loss of precision +(currently chopping to nine decimal places) so that it may not match +the version of the XS module anymore. Quoting the $VERSION declaration +to make it a string is recommended if long version numbers are used. + +=head2 The PROTOTYPES: Keyword + +The PROTOTYPES: keyword corresponds to B's C<-prototypes> and +C<-noprototypes> options. This keyword overrides the command line options. +Prototypes are disabled 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. +Note that B will nag you if you don't explicitly enable or disable +prototypes, with: + + Please specify prototyping behavior for Foo.xs (see perlxs manual) + +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 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 for information about Perl +prototypes. + + bool_t + rpcb_gettime(timep, ...) + time_t timep = NO_INIT + PROTOTYPE: $;$ + PREINIT: + char *host = "localhost"; + CODE: + if( items > 1 ) + 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 +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 which contain the +index of the alias which was used. When the XSUB is called with its +declared name C will be 0. + +The following example will create aliases C and +C 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 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 in such a way as to accept the number +of parameters supplied by perl's overload system. For most overload +methods, it will be three parameters; for the C function it will +be four. However, the bitwise operators C<&>, C<|>, C<^>, and C<~> may be +called with three I five arguments (see L). + +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). + +Since, as mentioned above, bitwise operators may take extra arguments, you +may want to use something like C<(lobj, robj, swap, ...)> (with +literal C<...>) as your parameter list. + +=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 for more details. + +=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, 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, +and C for this C. The setter macro is given cv, +and the function pointer. + +The default value is C and C. +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 with offsets being C, C, C, +C. Then one can use + + #define XSINTERFACE_FUNC_BYOFFSET(ret,cv,f) \ + ((XSINTERFACE_CVT_ANON(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 contains our C 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. This feature is +mildly deprecated in favour of the C directive, as documented +below. + + INCLUDE: cat Rpcb1.xsh | + +Do not use this to run perl: C will run the perl that +happens to be the first in your path and not necessarily the same perl that is +used to run C. See L<"The INCLUDE_COMMAND: Keyword">. + +=head2 The INCLUDE_COMMAND: Keyword + +Runs the supplied command and includes its output into the current XS +document. C assigns special meaning to the C<$^X> token +in that it runs the same perl interpreter that is running C: + + INCLUDE_COMMAND: cat Rpcb1.xsh + + INCLUDE_COMMAND: $^X -e ... + +=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 ALIAS: +variable (see L<"The ALIAS: Keyword">), or maybe via the C variable +(see L<"Variable-length Parameter Lists">). The last CASE: becomes the +B case if it is not associated with a conditional. The following +example shows CASE switched via C with a function C +having an alias C. When the function is called as +C its parameters are the usual C<(char *host, time_t *timep)>, +but when the function is called as C 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 EXPORT_XSUB_SYMBOLS: Keyword + +The EXPORT_XSUB_SYMBOLS: keyword is likely something you will never need. +In perl versions earlier than 5.16.0, this keyword does nothing. Starting +with 5.16, XSUB symbols are no longer exported by default. That is, they +are C functions. If you include + + EXPORT_XSUB_SYMBOLS: ENABLE + +in your XS code, the XSUBs following this line will not be declared C. +You can later disable this with + + EXPORT_XSUB_SYMBOLS: DISABLE + +which, again, is the default that you should probably never change. +You cannot use this keyword on versions of perl before 5.16 to make +XSUBs C. + +=head2 The & Unary Operator + +The C<&> unary operator in the INPUT: section is used to tell B +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 or C but not an C or C). + +The following XSUB will generate incorrect C code. The B compiler will +turn this into code which calls C with parameters C<(char +*host, time_t timep)>, but the real C wants the C +parameter to be of type C rather than C. + + bool_t + rpcb_gettime(host,timep) + char *host + time_t timep + OUTPUT: + timep + +That problem is corrected by using the C<&> operator. The B compiler +will now turn this into code which calls C correctly with +parameters C<(char *host, time_t *timep)>. It does this by carrying the +C<&> through, so the function call looks like C. + + bool_t + rpcb_gettime(host,timep) + char *host + time_t &timep + OUTPUT: + timep + +=head2 Inserting POD, Comments and C Preprocessor Directives + +C preprocessor directives are allowed within BOOT:, PREINIT: INIT:, CODE:, +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 +C and XS language sections. POD must be terminated with a C<=cut> command; +C will exit with an error if it does not. It is very unlikely that +human generated C code will be mistaken for POD, as most indenting styles +result in whitespace in front of any line starting with C<=>. Machine +generated XS files may fall into this trap unless care is taken to +ensure that a space breaks the sequence "\n=". + +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 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, 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-Emethod() 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, 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 then the C++ C function will be +called and C 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 then the C++ C 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, to be given as the first +argument. + + color * + color::new() + +The generated C++ code will call C. + + 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) 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 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, +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 which converts negative values to C, or +maybe croak()s. After this the return value of type C +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, 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.) + +If the same C type is used in several different contexts which require +different translations, C several new types mapped to this C type, +and create separate F 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 or B 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. 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 will be created for C. The Perl +object will be blessed in a class matching the name of the C +type, with the tag C 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 +L 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 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 specifying +the C<-g> (C<--global>) option with h2xs (see L). + +Below is an example module that makes use of the macros. + + #define PERL_NO_GET_CONTEXT + #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) + 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); + } + OUTPUT: + RETVAL + + char * + get_mouse_name(index) + int index + PREINIT: + dMY_CXT; + CODE: + if (index > MY_CXT.count) + croak("There are only 3 blind mice."); + else + RETVAL = MY_CXT.name[index - 1]; + OUTPUT: + RETVAL + + void + CLONE(...) + CODE: + MY_CXT_CLONE; + +=head3 MY_CXT 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 always be called C. The other +C macros assume the existence of the C typedef name. + +Declare a typedef named C 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. + +=item MY_CXT_INIT + +The MY_CXT_INIT macro initializes storage for the C struct. + +It I 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 L below.) + +=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 struct. For +example, if C is + + typedef struct { + int index; + } my_cxt_t; + +then use this to access the C member + + dMY_CXT; + MY_CXT.index = 2; + +=item aMY_CXT/pMY_CXT + +C 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/C macros, eg + + void sub1() { + dMY_CXT; + MY_CXT.index = 1; + sub2(aMY_CXT); + } + + void sub2(pMY_CXT) { + MY_CXT.index = 2; + } + +Analogously to C, 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, C<_pMY_CXT> and C. + +=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 (typically via the package's +C 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 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 the Perl core, the wrapping +does not take place before Perl 5.28. Starting in that release you can + + #define PERL_REENTRANT + +in your code to enable the wrapping. It is advisable to do so if you +are using such functions, as intermixing the C<_r>-forms (as Perl compiled +for multithreaded operation will do) and the C<_r>-less forms is neither +well-defined (inconsistent results, data corruption, or even crashes +become more likely), nor is it very portable. Unfortunately, not all +systems have all the C<_r> forms, but using this C<#define> gives you +whatever protection that Perl is aware is available on each system. + +=head1 EXAMPLES + +File C: Interface to some ONC+ RPC bind library functions. + + #define PERL_NO_GET_CONTEXT + #include "EXTERN.h" + #include "perl.h" + #include "XSUB.h" + + #include + + 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: Custom typemap for RPC.xs. (cf. L) + + TYPEMAP + Netconfig * T_PTROBJ + +File C: 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: 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 CAVEATS + +XS code has full access to system calls including C library functions. +It thus has the capability of interfering with things that the Perl core +or other modules have set up, such as signal handlers or file handles. +It could mess with the memory, or any number of harmful things. Don't. + +Some modules have an event loop, waiting for user-input. It is highly +unlikely that two such modules would work adequately together in a +single Perl application. + +In general, the perl interpreter views itself as the center of the +universe as far as the Perl program goes. XS code is viewed as a +help-mate, to accomplish things that perl doesn't do, or doesn't do fast +enough, but always subservient to perl. The closer XS code adheres to +this model, the less likely conflicts will occur. + +One area where there has been conflict is in regards to C locales. (See +L.) perl, with one exception and unless told otherwise, +sets up the underlying locale the program is running in to the locale +passed +into it from the environment. This is an important difference from a +generic C language program, where the underlying locale is the "C" +locale unless the program changes it. As of v5.20, this underlying +locale is completely hidden from pure Perl code outside the lexical +scope of C> except for a couple of function calls in the +POSIX module which of necessity use it. But the underlying locale, with +that +one exception is exposed to XS code, affecting all C library routines +whose behavior is locale-dependent. Your XS code better not assume that +the underlying locale is "C". The exception is the +L|perllocale/Category LC_NUMERIC: Numeric Formatting> +locale category, and the reason it is an exception is that experience +has shown that it can be problematic for XS code, whereas we have not +had reports of problems with the +L. And the reason +for this one category being problematic is that the character used as a +decimal point can vary. Many European languages use a comma, whereas +English, and hence Perl are expecting a dot (U+002E: FULL STOP). Many +modules can handle only the radix character being a dot, and so perl +attempts to make it so. Up through Perl v5.20, the attempt was merely +to set C upon startup to the C<"C"> locale. Any +L otherwise would change +it; this caused some failures. Therefore, starting in v5.22, perl tries +to keep C always set to C<"C"> for XS code. + +To summarize, here's what to expect and how to handle locales in XS code: + +=over + +=item Non-locale-aware XS code + +Keep in mind that even if you think your code is not locale-aware, it +may call a library function that is. Hopefully the man page for such +a function will indicate that dependency, but the documentation is +imperfect. + +The current locale is exposed to XS code except possibly C +(explained in the next paragraph). +There have not been reports of problems with the other categories. +Perl initializes things on start-up so that the current locale is the +one which is indicated by the user's environment in effect at that time. +See L. + +However, up through v5.20, Perl initialized things on start-up so that +C was set to the "C" locale. But if any code anywhere +changed it, it would stay changed. This means that your module can't +count on C being something in particular, and you can't +expect floating point numbers (including version strings) to have dots +in them. If you don't allow for a non-dot, your code could break if +anyone anywhere changed the locale. For this reason, v5.22 changed +the behavior so that Perl tries to keep C in the "C" locale +except around the operations internally where it should be something +else. Misbehaving XS code will always be able to change the locale +anyway, but the most common instance of this is checked for and +handled. + +=item Locale-aware XS code + +If the locale from the user's environment is desired, there should be no +need for XS code to set the locale except for C, as perl has +already set the others up. XS code should avoid changing the locale, as +it can adversely affect other, unrelated, code and may not be +thread-safe. To minimize problems, the macros +L, +L, and +L should be used to affect any needed +change. + +But, starting with Perl v5.28, locales are thread-safe on platforms that +support this functionality. Windows has this starting with Visual +Studio 2005. Many other modern platforms support the thread-safe POSIX +2008 functions. The C C<#define> C will be +defined iff this build is using these. From Perl-space, the read-only +variable C<${SAFE_LOCALES}> is 1 if either the build is not threaded, or +if C is defined; otherwise it is 0. + +The way this works under-the-hood is that every thread has a choice of +using a locale specific to it (this is the Windows and POSIX 2008 +functionality), or the global locale that is accessible to all threads +(this is the functionality that has always been there). The +implementations for Windows and POSIX are completely different. On +Windows, the runtime can be set up so that the standard +L> function either only knows about the global locale or +the locale for this thread. On POSIX, C always deals with +the global locale, and other functions have been created to handle +per-thread locales. Perl makes this transparent to perl-space code. It +continues to use C, and the interpreter translates +that into the per-thread functions. + +All other locale-senstive functions automatically use the per-thread +locale, if that is turned on, and failing that, the global locale. Thus +calls to C are ineffective on POSIX systems for the current +thread if that thread is using a per-thread locale. If perl is compiled +for single-thread operation, it does not use the per-thread functions, +so C does work as expected. + +If you have loaded the L> module you can use the methods given +in L to call L|POSIX/setlocale> to safely +change or query the locale (on systems where it is safe to do so), or +you can use the new 5.28 function L instead, +which is a drop-in replacement for the system L>, and +handles single-threaded and multi-threaded applications transparently. + +There are some locale-related library calls that still aren't +thread-safe because they return data in a buffer global to all threads. +In the past, these didn't matter as locales weren't thread-safe at all. +But now you have to be aware of them in case your module is called in a +multi-threaded application. The known ones are + + asctime() + ctime() + gcvt() [POSIX.1-2001 only (function removed in POSIX.1-2008)] + getdate() + wcrtomb() if its final argument is NULL + wcsrtombs() if its final argument is NULL + wcstombs() + wctomb() + +Some of these shouldn't really be called in a Perl application, and for +others there are thread-safe versions of these already implemented: + + asctime_r() + ctime_r() + Perl_langinfo() + +The C<_r> forms are automatically used, starting in Perl 5.28, if you +compile your code, with + + #define PERL_REENTRANT + +See also L. +You can use the methods given in L, to get the best available +locale-safe versions of these + + POSIX::localeconv() + POSIX::wcstombs() + POSIX::wctomb() + +And note, that some items returned by C are available +through L. + +The others shouldn't be used in a threaded application. + +Some modules may call a non-perl library that is locale-aware. This is +fine as long as it doesn't try to query or change the locale using the +system C. But if these do call the system C, +those calls may be ineffective. Instead, +L|perlapi/Perl_setlocale> works in all circumstances. +Plain setlocale is ineffective on multi-threaded POSIX 2008 systems. It +operates only on the global locale, whereas each thread has its own +locale, paying no attention to the global one. Since converting +these non-Perl libraries to C is out of the question, +there is a new function in v5.28 +L|perlapi/switch_to_global_locale> that will +switch the thread it is called from so that any system C +calls will have their desired effect. The function +L|perlapi/sync_locale> must be called before returning to +perl. + +This thread can change the locale all it wants and it won't affect any +other thread, except any that also have been switched to the global +locale. This means that a multi-threaded application can have a single +thread using an alien library without a problem; but no more than a +single thread can be so-occupied. Bad results likely will happen. + +In perls without multi-thread locale support, some alien libraries, +such as C change locales. This can cause problems for the Perl +core and other modules. For these, before control is returned to +perl, starting in v5.20.1, calling the function +L from XS should be sufficient to +avoid most of these problems. Prior to this, you need a pure Perl +statement that does this: + + POSIX::setlocale(LC_ALL, POSIX::setlocale(LC_ALL)); + +or use the methods given in L. + +=back + +=head1 XS VERSION + +This document covers features supported by C +(also known as C) 3.13_01. + +=head1 AUTHOR + +Originally written by Dean Roehrich >. + +Maintained since 1996 by The Perl Porters >. diff --git a/lib/perlxstut.pod b/lib/perlxstut.pod new file mode 100644 index 0000000..ef154ad --- /dev/null +++ b/lib/perlxstut.pod @@ -0,0 +1,1401 @@ +=head1 NAME + +perlxstut - Tutorial for writing XSUBs + +=head1 DESCRIPTION + +This tutorial will educate the reader on the steps involved in creating +a Perl extension. The reader is assumed to have access to L, +L and L. + +This tutorial starts with very simple examples and becomes more complex, +with each new example adding new features. Certain concepts may not be +completely explained until later in the tutorial in order to slowly ease +the reader into building extensions. + +This tutorial was written from a Unix point of view. Where I know them +to be otherwise different for other platforms (e.g. Win32), I will list +them. If you find something that was missed, please let me know. + +=head1 SPECIAL NOTES + +=head2 make + +This tutorial assumes that the make program that Perl is configured to +use is called C. Instead of running "make" in the examples that +follow, you may have to substitute whatever make program Perl has been +configured to use. Running B should tell you what it is. + +=head2 Version caveat + +When writing a Perl extension for general consumption, one should expect that +the extension will be used with versions of Perl different from the +version available on your machine. Since you are reading this document, +the version of Perl on your machine is probably 5.005 or later, but the users +of your extension may have more ancient versions. + +To understand what kinds of incompatibilities one may expect, and in the rare +case that the version of Perl on your machine is older than this document, +see the section on "Troubleshooting these Examples" for more information. + +If your extension uses some features of Perl which are not available on older +releases of Perl, your users would appreciate an early meaningful warning. +You would probably put this information into the F file, but nowadays +installation of extensions may be performed automatically, guided by F +module or other tools. + +In MakeMaker-based installations, F provides the earliest +opportunity to perform version checks. One can put something like this +in F for this purpose: + + eval { require 5.007 } + or die < build them, but you must link the XSUBs subroutines with the +rest of Perl, creating a new executable. This situation is similar to +Perl 4. + +This tutorial can still be used on such a system. The XSUB build mechanism +will check the system and build a dynamically-loadable library if possible, +or else a static library and then, optionally, a new statically-linked +executable with that static library linked in. + +Should you wish to build a statically-linked executable on a system which +can dynamically load libraries, you may, in all the following examples, +where the command "C" with no arguments is executed, run the command +"C" instead. + +If you have generated such a statically-linked executable by choice, then +instead of saying "C", you should say "C". +On systems that cannot build dynamically-loadable libraries at all, simply +saying "C" is sufficient. + +=head2 Threads and PERL_NO_GET_CONTEXT + +For threaded builds, perl requires the context pointer for the current +thread, without C, perl will call a function to +retrieve the context. + +For improved performance, include: + + #define PERL_NO_GET_CONTEXT + +as shown below. + +For more details, see L. + +=head1 TUTORIAL + +Now let's go on with the show! + +=head2 EXAMPLE 1 + +Our first extension will be very simple. When we call the routine in the +extension, it will print out a well-known message and return. + +Run "C". This creates a directory named Mytest, +possibly under ext/ if that directory exists in the current working +directory. Several files will be created under the Mytest dir, including +MANIFEST, Makefile.PL, lib/Mytest.pm, Mytest.xs, t/Mytest.t, and Changes. + +The MANIFEST file contains the names of all the files just created in the +Mytest directory. + +The file Makefile.PL should look something like this: + + use ExtUtils::MakeMaker; + # See lib/ExtUtils/MakeMaker.pm for details of how to influence + # the contents of the Makefile that is written. + WriteMakefile( + NAME => 'Mytest', + VERSION_FROM => 'Mytest.pm', # finds $VERSION + LIBS => [''], # e.g., '-lm' + DEFINE => '', # e.g., '-DHAVE_SOMETHING' + INC => '', # e.g., '-I/usr/include/other' + ); + +The file Mytest.pm should start with something like this: + + package Mytest; + + use 5.008008; + use strict; + use warnings; + + require Exporter; + + our @ISA = qw(Exporter); + our %EXPORT_TAGS = ( 'all' => [ qw( + + ) ] ); + + our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); + + our @EXPORT = qw( + + ); + + our $VERSION = '0.01'; + + require XSLoader; + XSLoader::load('Mytest', $VERSION); + + # Preloaded methods go here. + + 1; + __END__ + # Below is the stub of documentation for your module. You better + # edit it! + +The rest of the .pm file contains sample code for providing documentation for +the extension. + +Finally, the Mytest.xs file should look something like this: + + #define PERL_NO_GET_CONTEXT + #include "EXTERN.h" + #include "perl.h" + #include "XSUB.h" + + #include "ppport.h" + + MODULE = Mytest PACKAGE = Mytest + +Let's edit the .xs file by adding this to the end of the file: + + void + hello() + CODE: + printf("Hello, world!\n"); + +It is okay for the lines starting at the "CODE:" line to not be indented. +However, for readability purposes, it is suggested that you indent CODE: +one level and the lines following one more level. + +Now we'll run "C". This will create a real Makefile, +which make needs. Its output looks something like: + + % perl Makefile.PL + Checking if your kit is complete... + Looks good + Writing Makefile for Mytest + % + +Now, running make will produce output that looks something like this (some +long lines have been shortened for clarity and some extraneous lines have +been deleted): + + % make + cp lib/Mytest.pm blib/lib/Mytest.pm + perl xsubpp -typemap typemap Mytest.xs > Mytest.xsc && \ + mv Mytest.xsc Mytest.c + Please specify prototyping behavior for Mytest.xs (see perlxs manual) + cc -c Mytest.c + Running Mkbootstrap for Mytest () + chmod 644 Mytest.bs + rm -f blib/arch/auto/Mytest/Mytest.so + cc -shared -L/usr/local/lib Mytest.o -o blib/arch/auto/Mytest/Mytest.so + + chmod 755 blib/arch/auto/Mytest/Mytest.so + cp Mytest.bs blib/arch/auto/Mytest/Mytest.bs + chmod 644 blib/arch/auto/Mytest/Mytest.bs + Manifying blib/man3/Mytest.3pm + % + +You can safely ignore the line about "prototyping behavior" - it is +explained in L. + +Perl has its own special way of easily writing test scripts, but for this +example only, we'll create our own test script. Create a file called hello +that looks like this: + + #! /opt/perl5/bin/perl + + use ExtUtils::testlib; + + use Mytest; + + Mytest::hello(); + +Now we make the script executable (C), run the script +and we should see the following output: + + % ./hello + Hello, world! + % + +=head2 EXAMPLE 2 + +Now let's add to our extension a subroutine that will take a single numeric +argument as input and return 1 if the number is even or 0 if the number +is odd. + +Add the following to the end of Mytest.xs: + + int + is_even(input) + int input + CODE: + RETVAL = (input % 2 == 0); + OUTPUT: + RETVAL + +There does not need to be whitespace at the start of the "C" +line, but it is useful for improving readability. Placing a semi-colon at +the end of that line is also optional. Any amount and kind of whitespace +may be placed between the "C" and "C". + +Now re-run make to rebuild our new shared library. + +Now perform the same steps as before, generating a Makefile from the +Makefile.PL file, and running make. + +In order to test that our extension works, we now need to look at the +file Mytest.t. This file is set up to imitate the same kind of testing +structure that Perl itself has. Within the test script, you perform a +number of tests to confirm the behavior of the extension, printing "ok" +when the test is correct, "not ok" when it is not. + + use Test::More tests => 4; + BEGIN { use_ok('Mytest') }; + + ######################### + + # Insert your test code below, the Test::More module is use()ed here + # so read its man page ( perldoc Test::More ) for help writing this + # test script. + + is(&Mytest::is_even(0), 1); + is(&Mytest::is_even(1), 0); + is(&Mytest::is_even(2), 1); + +We will be calling the test script through the command "C". You +should see output that looks something like this: + + %make test + PERL_DL_NONLAZY=1 /usr/bin/perl "-MExtUtils::Command::MM" "-e" + "test_harness(0, 'blib/lib', 'blib/arch')" t/*.t + t/Mytest....ok + All tests successful. + Files=1, Tests=4, 0 wallclock secs ( 0.03 cusr + 0.00 csys = 0.03 CPU) + % + +=head2 What has gone on? + +The program h2xs is the starting point for creating extensions. In later +examples we'll see how we can use h2xs to read header files and generate +templates to connect to C routines. + +h2xs creates a number of files in the extension directory. The file +Makefile.PL is a perl script which will generate a true Makefile to build +the extension. We'll take a closer look at it later. + +The .pm and .xs files contain the meat of the extension. The .xs file holds +the C routines that make up the extension. The .pm file contains routines +that tell Perl how to load your extension. + +Generating the Makefile and running C created a directory called blib +(which stands for "build library") in the current working directory. This +directory will contain the shared library that we will build. Once we have +tested it, we can install it into its final location. + +Invoking the test script via "C" did something very important. +It invoked perl with all those C<-I> arguments so that it could find the +various files that are part of the extension. It is I important that +while you are still testing extensions that you use "C". If you +try to run the test script all by itself, you will get a fatal error. +Another reason it is important to use "C" to run your test +script is that if you are testing an upgrade to an already-existing version, +using "C" ensures that you will test your new extension, not the +already-existing version. + +When Perl sees a C, it searches for a file with the same name +as the C'd extension that has a .pm suffix. If that file cannot be found, +Perl dies with a fatal error. The default search path is contained in the +C<@INC> array. + +In our case, Mytest.pm tells perl that it will need the Exporter and Dynamic +Loader extensions. It then sets the C<@ISA> and C<@EXPORT> arrays and the +C<$VERSION> scalar; finally it tells perl to bootstrap the module. Perl +will call its dynamic loader routine (if there is one) and load the shared +library. + +The two arrays C<@ISA> and C<@EXPORT> are very important. The C<@ISA> +array contains a list of other packages in which to search for methods (or +subroutines) that do not exist in the current package. This is usually +only important for object-oriented extensions (which we will talk about +much later), and so usually doesn't need to be modified. + +The C<@EXPORT> array tells Perl which of the extension's variables and +subroutines should be placed into the calling package's namespace. Because +you don't know if the user has already used your variable and subroutine +names, it's vitally important to carefully select what to export. Do I +export method or variable names I without a good reason. + +As a general rule, if the module is trying to be object-oriented then don't +export anything. If it's just a collection of functions and variables, then +you can export them via another array, called C<@EXPORT_OK>. This array +does not automatically place its subroutine and variable names into the +namespace unless the user specifically requests that this be done. + +See L for more information. + +The C<$VERSION> variable is used to ensure that the .pm file and the shared +library are "in sync" with each other. Any time you make changes to +the .pm or .xs files, you should increment the value of this variable. + +=head2 Writing good test scripts + +The importance of writing good test scripts cannot be over-emphasized. You +should closely follow the "ok/not ok" style that Perl itself uses, so that +it is very easy and unambiguous to determine the outcome of each test case. +When you find and fix a bug, make sure you add a test case for it. + +By running "C", you ensure that your Mytest.t script runs and uses +the correct version of your extension. If you have many test cases, +save your test files in the "t" directory and use the suffix ".t". +When you run "C", all of these test files will be executed. + +=head2 EXAMPLE 3 + +Our third extension will take one argument as its input, round off that +value, and set the I to the rounded value. + +Add the following to the end of Mytest.xs: + + void + round(arg) + double arg + CODE: + if (arg > 0.0) { + arg = floor(arg + 0.5); + } else if (arg < 0.0) { + arg = ceil(arg - 0.5); + } else { + arg = 0.0; + } + OUTPUT: + arg + +Edit the Makefile.PL file so that the corresponding line looks like this: + + 'LIBS' => ['-lm'], # e.g., '-lm' + +Generate the Makefile and run make. Change the test number in Mytest.t to +"9" and add the following tests: + + $i = -1.5; &Mytest::round($i); is( $i, -2.0 ); + $i = -1.1; &Mytest::round($i); is( $i, -1.0 ); + $i = 0.0; &Mytest::round($i); is( $i, 0.0 ); + $i = 0.5; &Mytest::round($i); is( $i, 1.0 ); + $i = 1.2; &Mytest::round($i); is( $i, 1.0 ); + +Running "C" should now print out that all nine tests are okay. + +Notice that in these new test cases, the argument passed to round was a +scalar variable. You might be wondering if you can round a constant or +literal. To see what happens, temporarily add the following line to Mytest.t: + + &Mytest::round(3); + +Run "C" and notice that Perl dies with a fatal error. Perl won't +let you change the value of constants! + +=head2 What's new here? + +=over 4 + +=item * + +We've made some changes to Makefile.PL. In this case, we've specified an +extra library to be linked into the extension's shared library, the math +library libm in this case. We'll talk later about how to write XSUBs that +can call every routine in a library. + +=item * + +The value of the function is not being passed back as the function's return +value, but by changing the value of the variable that was passed into the +function. You might have guessed that when you saw that the return value +of round is of type "void". + +=back + +=head2 Input and Output Parameters + +You specify the parameters that will be passed into the XSUB on the line(s) +after you declare the function's return value and name. Each input parameter +line starts with optional whitespace, and may have an optional terminating +semicolon. + +The list of output parameters occurs at the very end of the function, just +after the OUTPUT: directive. The use of RETVAL tells Perl that you +wish to send this value back as the return value of the XSUB function. In +Example 3, we wanted the "return value" placed in the original variable +which we passed in, so we listed it (and not RETVAL) in the OUTPUT: section. + +=head2 The XSUBPP Program + +The B program takes the XS code in the .xs file and translates it into +C code, placing it in a file whose suffix is .c. The C code created makes +heavy use of the C functions within Perl. + +=head2 The TYPEMAP file + +The B program uses rules to convert from Perl's data types (scalar, +array, etc.) to C's data types (int, char, etc.). These rules are stored +in the typemap file ($PERLLIB/ExtUtils/typemap). There's a brief discussion +below, but all the nitty-gritty details can be found in L. +If you have a new-enough version of perl (5.16 and up) or an upgraded +XS compiler (C 3.13_01 or better), then you can inline +typemaps in your XS instead of writing separate files. +Either way, this typemap thing is split into three parts: + +The first section maps various C data types to a name, which corresponds +somewhat with the various Perl types. The second section contains C code +which B uses to handle input parameters. The third section contains +C code which B uses to handle output parameters. + +Let's take a look at a portion of the .c file created for our extension. +The file name is Mytest.c: + + XS(XS_Mytest_round) + { + dXSARGS; + if (items != 1) + Perl_croak(aTHX_ "Usage: Mytest::round(arg)"); + PERL_UNUSED_VAR(cv); /* -W */ + { + double arg = (double)SvNV(ST(0)); /* XXXXX */ + if (arg > 0.0) { + arg = floor(arg + 0.5); + } else if (arg < 0.0) { + arg = ceil(arg - 0.5); + } else { + arg = 0.0; + } + sv_setnv(ST(0), (double)arg); /* XXXXX */ + SvSETMAGIC(ST(0)); + } + XSRETURN_EMPTY; + } + +Notice the two lines commented with "XXXXX". If you check the first part +of the typemap file (or section), you'll see that doubles are of type +T_DOUBLE. In the INPUT part of the typemap, an argument that is T_DOUBLE +is assigned to the variable arg by calling the routine SvNV on something, +then casting it to double, then assigned to the variable arg. Similarly, +in the OUTPUT section, once arg has its final value, it is passed to the +sv_setnv function to be passed back to the calling subroutine. These two +functions are explained in L; we'll talk more later about what +that "ST(0)" means in the section on the argument stack. + +=head2 Warning about Output Arguments + +In general, it's not a good idea to write extensions that modify their input +parameters, as in Example 3. Instead, you should probably return multiple +values in an array and let the caller handle them (we'll do this in a later +example). However, in order to better accommodate calling pre-existing C +routines, which often do modify their input parameters, this behavior is +tolerated. + +=head2 EXAMPLE 4 + +In this example, we'll now begin to write XSUBs that will interact with +pre-defined C libraries. To begin with, we will build a small library of +our own, then let h2xs write our .pm and .xs files for us. + +Create a new directory called Mytest2 at the same level as the directory +Mytest. In the Mytest2 directory, create another directory called mylib, +and cd into that directory. + +Here we'll create some files that will generate a test library. These will +include a C source file and a header file. We'll also create a Makefile.PL +in this directory. Then we'll make sure that running make at the Mytest2 +level will automatically run this Makefile.PL file and the resulting Makefile. + +In the mylib directory, create a file mylib.h that looks like this: + + #define TESTVAL 4 + + extern double foo(int, long, const char*); + +Also create a file mylib.c that looks like this: + + #include + #include "./mylib.h" + + double + foo(int a, long b, const char *c) + { + return (a + b + atof(c) + TESTVAL); + } + +And finally create a file Makefile.PL that looks like this: + + use ExtUtils::MakeMaker; + $Verbose = 1; + WriteMakefile( + NAME => 'Mytest2::mylib', + SKIP => [qw(all static static_lib dynamic dynamic_lib)], + clean => {'FILES' => 'libmylib$(LIB_EXT)'}, + ); + + + sub MY::top_targets { + ' + all :: static + + pure_all :: static + + static :: libmylib$(LIB_EXT) + + libmylib$(LIB_EXT): $(O_FILES) + $(AR) cr libmylib$(LIB_EXT) $(O_FILES) + $(RANLIB) libmylib$(LIB_EXT) + + '; + } + +Make sure you use a tab and not spaces on the lines beginning with "$(AR)" +and "$(RANLIB)". Make will not function properly if you use spaces. +It has also been reported that the "cr" argument to $(AR) is unnecessary +on Win32 systems. + +We will now create the main top-level Mytest2 files. Change to the directory +above Mytest2 and run the following command: + + % h2xs -O -n Mytest2 ./Mytest2/mylib/mylib.h + +This will print out a warning about overwriting Mytest2, but that's okay. +Our files are stored in Mytest2/mylib, and will be untouched. + +The normal Makefile.PL that h2xs generates doesn't know about the mylib +directory. We need to tell it that there is a subdirectory and that we +will be generating a library in it. Let's add the argument MYEXTLIB to +the WriteMakefile call so that it looks like this: + + WriteMakefile( + 'NAME' => 'Mytest2', + 'VERSION_FROM' => 'Mytest2.pm', # finds $VERSION + 'LIBS' => [''], # e.g., '-lm' + 'DEFINE' => '', # e.g., '-DHAVE_SOMETHING' + 'INC' => '', # e.g., '-I/usr/include/other' + 'MYEXTLIB' => 'mylib/libmylib$(LIB_EXT)', + ); + +and then at the end add a subroutine (which will override the pre-existing +subroutine). Remember to use a tab character to indent the line beginning +with "cd"! + + sub MY::postamble { + ' + $(MYEXTLIB): mylib/Makefile + cd mylib && $(MAKE) $(PASSTHRU) + '; + } + +Let's also fix the MANIFEST file so that it accurately reflects the contents +of our extension. The single line that says "mylib" should be replaced by +the following three lines: + + mylib/Makefile.PL + mylib/mylib.c + mylib/mylib.h + +To keep our namespace nice and unpolluted, edit the .pm file and change +the variable C<@EXPORT> to C<@EXPORT_OK>. Finally, in the +.xs file, edit the #include line to read: + + #include "mylib/mylib.h" + +And also add the following function definition to the end of the .xs file: + + double + foo(a,b,c) + int a + long b + const char * c + OUTPUT: + RETVAL + +Now we also need to create a typemap because the default Perl doesn't +currently support the C type. Include a new TYPEMAP +section in your XS code before the above function: + + TYPEMAP: <" and all should be well. There are some warnings on missing +tests for the Mytest2::mylib extension, but you can ignore them. + +=head2 What has happened here? + +Unlike previous examples, we've now run h2xs on a real include file. This +has caused some extra goodies to appear in both the .pm and .xs files. + +=over 4 + +=item * + +In the .xs file, there's now a #include directive with the absolute path to +the mylib.h header file. We changed this to a relative path so that we +could move the extension directory if we wanted to. + +=item * + +There's now some new C code that's been added to the .xs file. The purpose +of the C routine is to make the values that are #define'd in the +header file accessible by the Perl script (by calling either C or +C<&Mytest2::TESTVAL>). There's also some XS code to allow calls to the +C routine. + +=item * + +The .pm file originally exported the name C in the C<@EXPORT> array. +This could lead to name clashes. A good rule of thumb is that if the #define +is only going to be used by the C routines themselves, and not by the user, +they should be removed from the C<@EXPORT> array. Alternately, if you don't +mind using the "fully qualified name" of a variable, you could move most +or all of the items from the C<@EXPORT> array into the C<@EXPORT_OK> array. + +=item * + +If our include file had contained #include directives, these would not have +been processed by h2xs. There is no good solution to this right now. + +=item * + +We've also told Perl about the library that we built in the mylib +subdirectory. That required only the addition of the C variable +to the WriteMakefile call and the replacement of the postamble subroutine +to cd into the subdirectory and run make. The Makefile.PL for the +library is a bit more complicated, but not excessively so. Again we +replaced the postamble subroutine to insert our own code. This code +simply specified that the library to be created here was a static archive +library (as opposed to a dynamically loadable library) and provided the +commands to build it. + +=back + +=head2 Anatomy of .xs file + +The .xs file of L<"EXAMPLE 4"> contained some new elements. To understand +the meaning of these elements, pay attention to the line which reads + + MODULE = Mytest2 PACKAGE = Mytest2 + +Anything before this line is plain C code which describes which headers +to include, and defines some convenience functions. No translations are +performed on this part, apart from having embedded POD documentation +skipped over (see L) it goes into the generated output C file as is. + +Anything after this line is the description of XSUB functions. +These descriptions are translated by B into C code which +implements these functions using Perl calling conventions, and which +makes these functions visible from Perl interpreter. + +Pay a special attention to the function C. This name appears +twice in the generated .xs file: once in the first part, as a static C +function, then another time in the second part, when an XSUB interface to +this static C function is defined. + +This is quite typical for .xs files: usually the .xs file provides +an interface to an existing C function. Then this C function is defined +somewhere (either in an external library, or in the first part of .xs file), +and a Perl interface to this function (i.e. "Perl glue") is described in the +second part of .xs file. The situation in L<"EXAMPLE 1">, L<"EXAMPLE 2">, +and L<"EXAMPLE 3">, when all the work is done inside the "Perl glue", is +somewhat of an exception rather than the rule. + +=head2 Getting the fat out of XSUBs + +In L<"EXAMPLE 4"> the second part of .xs file contained the following +description of an XSUB: + + double + foo(a,b,c) + int a + long b + const char * c + OUTPUT: + RETVAL + +Note that in contrast with L<"EXAMPLE 1">, L<"EXAMPLE 2"> and L<"EXAMPLE 3">, +this description does not contain the actual I for what is done +during a call to Perl function foo(). To understand what is going +on here, one can add a CODE section to this XSUB: + + double + foo(a,b,c) + int a + long b + const char * c + CODE: + RETVAL = foo(a,b,c); + OUTPUT: + RETVAL + +However, these two XSUBs provide almost identical generated C code: B +compiler is smart enough to figure out the C section from the first +two lines of the description of XSUB. What about C section? In +fact, that is absolutely the same! The C section can be removed +as well, I section or C section> is not +specified: B can see that it needs to generate a function call +section, and will autogenerate the OUTPUT section too. Thus one can +shortcut the XSUB to become: + + double + foo(a,b,c) + int a + long b + const char * c + +Can we do the same with an XSUB + + int + is_even(input) + int input + CODE: + RETVAL = (input % 2 == 0); + OUTPUT: + RETVAL + +of L<"EXAMPLE 2">? To do this, one needs to define a C function C. As we saw in L, a proper place +for this definition is in the first part of .xs file. In fact a C function + + int + is_even(int arg) + { + return (arg % 2 == 0); + } + +is probably overkill for this. Something as simple as a C<#define> will +do too: + + #define is_even(arg) ((arg) % 2 == 0) + +After having this in the first part of .xs file, the "Perl glue" part becomes +as simple as + + int + is_even(input) + int input + +This technique of separation of the glue part from the workhorse part has +obvious tradeoffs: if you want to change a Perl interface, you need to +change two places in your code. However, it removes a lot of clutter, +and makes the workhorse part independent from idiosyncrasies of Perl calling +convention. (In fact, there is nothing Perl-specific in the above description, +a different version of B might have translated this to TCL glue or +Python glue as well.) + +=head2 More about XSUB arguments + +With the completion of Example 4, we now have an easy way to simulate some +real-life libraries whose interfaces may not be the cleanest in the world. +We shall now continue with a discussion of the arguments passed to the +B compiler. + +When you specify arguments to routines in the .xs file, you are really +passing three pieces of information for each argument listed. The first +piece is the order of that argument relative to the others (first, second, +etc). The second is the type of argument, and consists of the type +declaration of the argument (e.g., int, char*, etc). The third piece is +the calling convention for the argument in the call to the library function. + +While Perl passes arguments to functions by reference, +C passes arguments by value; to implement a C function which modifies data +of one of the "arguments", the actual argument of this C function would be +a pointer to the data. Thus two C functions with declarations + + int string_length(char *s); + int upper_case_char(char *cp); + +may have completely different semantics: the first one may inspect an array +of chars pointed by s, and the second one may immediately dereference C +and manipulate C<*cp> only (using the return value as, say, a success +indicator). From Perl one would use these functions in +a completely different manner. + +One conveys this info to B by replacing C<*> before the +argument by C<&>. C<&> means that the argument should be passed to a library +function by its address. The above two function may be XSUB-ified as + + int + string_length(s) + char * s + + int + upper_case_char(cp) + char &cp + +For example, consider: + + int + foo(a,b) + char &a + char * b + +The first Perl argument to this function would be treated as a char and +assigned to the variable a, and its address would be passed into the function +foo. The second Perl argument would be treated as a string pointer and assigned +to the variable b. The I of b would be passed into the function foo. +The actual call to the function foo that B generates would look like +this: + + foo(&a, b); + +B will parse the following function argument lists identically: + + char &a + char&a + char & a + +However, to help ease understanding, it is suggested that you place a "&" +next to the variable name and away from the variable type), and place a +"*" near the variable type, but away from the variable name (as in the +call to foo above). By doing so, it is easy to understand exactly what +will be passed to the C function; it will be whatever is in the "last +column". + +You should take great pains to try to pass the function the type of variable +it wants, when possible. It will save you a lot of trouble in the long run. + +=head2 The Argument Stack + +If we look at any of the C code generated by any of the examples except +example 1, you will notice a number of references to ST(n), where n is +usually 0. "ST" is actually a macro that points to the n'th argument +on the argument stack. ST(0) is thus the first argument on the stack and +therefore the first argument passed to the XSUB, ST(1) is the second +argument, and so on. + +When you list the arguments to the XSUB in the .xs file, that tells B +which argument corresponds to which of the argument stack (i.e., the first +one listed is the first argument, and so on). You invite disaster if you +do not list them in the same order as the function expects them. + +The actual values on the argument stack are pointers to the values passed +in. When an argument is listed as being an OUTPUT value, its corresponding +value on the stack (i.e., ST(0) if it was the first argument) is changed. +You can verify this by looking at the C code generated for Example 3. +The code for the round() XSUB routine contains lines that look like this: + + double arg = (double)SvNV(ST(0)); + /* Round the contents of the variable arg */ + sv_setnv(ST(0), (double)arg); + +The arg variable is initially set by taking the value from ST(0), then is +stored back into ST(0) at the end of the routine. + +XSUBs are also allowed to return lists, not just scalars. This must be +done by manipulating stack values ST(0), ST(1), etc, in a subtly +different way. See L for details. + +XSUBs are also allowed to avoid automatic conversion of Perl function arguments +to C function arguments. See L for details. Some people prefer +manual conversion by inspecting C even in the cases when automatic +conversion will do, arguing that this makes the logic of an XSUB call clearer. +Compare with L<"Getting the fat out of XSUBs"> for a similar tradeoff of +a complete separation of "Perl glue" and "workhorse" parts of an XSUB. + +While experts may argue about these idioms, a novice to Perl guts may +prefer a way which is as little Perl-guts-specific as possible, meaning +automatic conversion and automatic call generation, as in +L<"Getting the fat out of XSUBs">. This approach has the additional +benefit of protecting the XSUB writer from future changes to the Perl API. + +=head2 Extending your Extension + +Sometimes you might want to provide some extra methods or subroutines +to assist in making the interface between Perl and your extension simpler +or easier to understand. These routines should live in the .pm file. +Whether they are automatically loaded when the extension itself is loaded +or only loaded when called depends on where in the .pm file the subroutine +definition is placed. You can also consult L for an alternate +way to store and load your extra subroutines. + +=head2 Documenting your Extension + +There is absolutely no excuse for not documenting your extension. +Documentation belongs in the .pm file. This file will be fed to pod2man, +and the embedded documentation will be converted to the manpage format, +then placed in the blib directory. It will be copied to Perl's +manpage directory when the extension is installed. + +You may intersperse documentation and Perl code within the .pm file. +In fact, if you want to use method autoloading, you must do this, +as the comment inside the .pm file explains. + +See L for more information about the pod format. + +=head2 Installing your Extension + +Once your extension is complete and passes all its tests, installing it +is quite simple: you simply run "make install". You will either need +to have write permission into the directories where Perl is installed, +or ask your system administrator to run the make for you. + +Alternately, you can specify the exact directory to place the extension's +files by placing a "PREFIX=/destination/directory" after the make install +(or in between the make and install if you have a brain-dead version of make). +This can be very useful if you are building an extension that will eventually +be distributed to multiple systems. You can then just archive the files in +the destination directory and distribute them to your destination systems. + +=head2 EXAMPLE 5 + +In this example, we'll do some more work with the argument stack. The +previous examples have all returned only a single value. We'll now +create an extension that returns an array. + +This extension is very Unix-oriented (struct statfs and the statfs system +call). If you are not running on a Unix system, you can substitute for +statfs any other function that returns multiple values, you can hard-code +values to be returned to the caller (although this will be a bit harder +to test the error case), or you can simply not do this example. If you +change the XSUB, be sure to fix the test cases to match the changes. + +Return to the Mytest directory and add the following code to the end of +Mytest.xs: + + void + statfs(path) + char * path + INIT: + int i; + struct statfs buf; + + PPCODE: + i = statfs(path, &buf); + if (i == 0) { + XPUSHs(sv_2mortal(newSVnv(buf.f_bavail))); + XPUSHs(sv_2mortal(newSVnv(buf.f_bfree))); + XPUSHs(sv_2mortal(newSVnv(buf.f_blocks))); + XPUSHs(sv_2mortal(newSVnv(buf.f_bsize))); + XPUSHs(sv_2mortal(newSVnv(buf.f_ffree))); + XPUSHs(sv_2mortal(newSVnv(buf.f_files))); + XPUSHs(sv_2mortal(newSVnv(buf.f_type))); + } else { + XPUSHs(sv_2mortal(newSVnv(errno))); + } + +You'll also need to add the following code to the top of the .xs file, just +after the include of "XSUB.h": + + #include + +Also add the following code segment to Mytest.t while incrementing the "9" +tests to "11": + + @a = &Mytest::statfs("/blech"); + ok( scalar(@a) == 1 && $a[0] == 2 ); + @a = &Mytest::statfs("/"); + is( scalar(@a), 7 ); + +=head2 New Things in this Example + +This example added quite a few new concepts. We'll take them one at a time. + +=over 4 + +=item * + +The INIT: directive contains code that will be placed immediately after +the argument stack is decoded. C does not allow variable declarations at +arbitrary locations inside a function, +so this is usually the best way to declare local variables needed by the XSUB. +(Alternatively, one could put the whole C section into braces, and +put these declarations on top.) + +=item * + +This routine also returns a different number of arguments depending on the +success or failure of the call to statfs. If there is an error, the error +number is returned as a single-element array. If the call is successful, +then a 7-element array is returned. Since only one argument is passed into +this function, we need room on the stack to hold the 7 values which may be +returned. + +We do this by using the PPCODE: directive, rather than the CODE: directive. +This tells B that we will be managing the return values that will be +put on the argument stack by ourselves. + +=item * + +When we want to place values to be returned to the caller onto the stack, +we use the series of macros that begin with "XPUSH". There are five +different versions, for placing integers, unsigned integers, doubles, +strings, and Perl scalars on the stack. In our example, we placed a +Perl scalar onto the stack. (In fact this is the only macro which +can be used to return multiple values.) + +The XPUSH* macros will automatically extend the return stack to prevent +it from being overrun. You push values onto the stack in the order you +want them seen by the calling program. + +=item * + +The values pushed onto the return stack of the XSUB are actually mortal SV's. +They are made mortal so that once the values are copied by the calling +program, the SV's that held the returned values can be deallocated. +If they were not mortal, then they would continue to exist after the XSUB +routine returned, but would not be accessible. This is a memory leak. + +=item * + +If we were interested in performance, not in code compactness, in the success +branch we would not use C macros, but C macros, and would +pre-extend the stack before pushing the return values: + + EXTEND(SP, 7); + +The tradeoff is that one needs to calculate the number of return values +in advance (though overextending the stack will not typically hurt +anything but memory consumption). + +Similarly, in the failure branch we could use C I extending +the stack: the Perl function reference comes to an XSUB on the stack, thus +the stack is I large enough to take one return value. + +=back + +=head2 EXAMPLE 6 + +In this example, we will accept a reference to an array as an input +parameter, and return a reference to an array of hashes. This will +demonstrate manipulation of complex Perl data types from an XSUB. + +This extension is somewhat contrived. It is based on the code in +the previous example. It calls the statfs function multiple times, +accepting a reference to an array of filenames as input, and returning +a reference to an array of hashes containing the data for each of the +filesystems. + +Return to the Mytest directory and add the following code to the end of +Mytest.xs: + + SV * + multi_statfs(paths) + SV * paths + INIT: + AV * results; + SSize_t numpaths = 0, n; + int i; + struct statfs buf; + + SvGETMAGIC(paths); + if ((!SvROK(paths)) + || (SvTYPE(SvRV(paths)) != SVt_PVAV) + || ((numpaths = av_top_index((AV *)SvRV(paths))) < 0)) + { + XSRETURN_UNDEF; + } + results = (AV *)sv_2mortal((SV *)newAV()); + CODE: + for (n = 0; n <= numpaths; n++) { + HV * rh; + STRLEN l; + char * fn = SvPV(*av_fetch((AV *)SvRV(paths), n, 0), l); + + i = statfs(fn, &buf); + if (i != 0) { + av_push(results, newSVnv(errno)); + continue; + } + + rh = (HV *)sv_2mortal((SV *)newHV()); + + hv_store(rh, "f_bavail", 8, newSVnv(buf.f_bavail), 0); + hv_store(rh, "f_bfree", 7, newSVnv(buf.f_bfree), 0); + hv_store(rh, "f_blocks", 8, newSVnv(buf.f_blocks), 0); + hv_store(rh, "f_bsize", 7, newSVnv(buf.f_bsize), 0); + hv_store(rh, "f_ffree", 7, newSVnv(buf.f_ffree), 0); + hv_store(rh, "f_files", 7, newSVnv(buf.f_files), 0); + hv_store(rh, "f_type", 6, newSVnv(buf.f_type), 0); + + av_push(results, newRV_inc((SV *)rh)); + } + RETVAL = newRV_inc((SV *)results); + OUTPUT: + RETVAL + +And add the following code to Mytest.t, while incrementing the "11" +tests to "13": + + $results = Mytest::multi_statfs([ '/', '/blech' ]); + ok( ref $results->[0] ); + ok( ! ref $results->[1] ); + +=head2 New Things in this Example + +There are a number of new concepts introduced here, described below: + +=over 4 + +=item * + +This function does not use a typemap. Instead, we declare it as accepting +one SV* (scalar) parameter, and returning an SV* value, and we take care of +populating these scalars within the code. Because we are only returning +one value, we don't need a C directive - instead, we use C +and C directives. + +=item * + +When dealing with references, it is important to handle them with caution. +The C block first calls SvGETMAGIC(paths), in case +paths is a tied variable. Then it checks that C returns +true, which indicates that paths is a valid reference. (Simply +checking C won't trigger FETCH on a tied variable.) It +then verifies that the object referenced by paths is an array, using C +to dereference paths, and C to discover its type. As an added test, +it checks that the array referenced by paths is non-empty, using the +C function (which returns -1 if the array is empty). The +XSRETURN_UNDEF macro is used to abort the XSUB and return the undefined value +whenever all three of these conditions are not met. + +=item * + +We manipulate several arrays in this XSUB. Note that an array is represented +internally by an AV* pointer. The functions and macros for manipulating +arrays are similar to the functions in Perl: C returns the +highest index in an AV*, much like $#array; C fetches a single scalar +value from an array, given its index; C pushes a scalar value onto the +end of the array, automatically extending the array as necessary. + +Specifically, we read pathnames one at a time from the input array, and +store the results in an output array (results) in the same order. If +statfs fails, the element pushed onto the return array is the value of +errno after the failure. If statfs succeeds, though, the value pushed +onto the return array is a reference to a hash containing some of the +information in the statfs structure. + +As with the return stack, it would be possible (and a small performance win) +to pre-extend the return array before pushing data into it, since we know +how many elements we will return: + + av_extend(results, numpaths); + +=item * + +We are performing only one hash operation in this function, which is storing +a new scalar under a key using C. A hash is represented by an HV* +pointer. Like arrays, the functions for manipulating hashes from an XSUB +mirror the functionality available from Perl. See L and L +for details. + +=item * + +To create a reference, we use the C function. Note that you can +cast an AV* or an HV* to type SV* in this case (and many others). This +allows you to take references to arrays, hashes and scalars with the same +function. Conversely, the C function always returns an SV*, which may +need to be cast to the appropriate type if it is something other than a +scalar (check with C). + +=item * + +At this point, xsubpp is doing very little work - the differences between +Mytest.xs and Mytest.c are minimal. + +=back + +=head2 EXAMPLE 7 (Coming Soon) + +XPUSH args AND set RETVAL AND assign return value to array + +=head2 EXAMPLE 8 (Coming Soon) + +Setting $! + +=head2 EXAMPLE 9 Passing open files to XSes + +You would think passing files to an XS is difficult, with all the +typeglobs and stuff. Well, it isn't. + +Suppose that for some strange reason we need a wrapper around the +standard C library function C. This is all we need: + + #define PERLIO_NOT_STDIO 0 + #define PERL_NO_GET_CONTEXT + #include "EXTERN.h" + #include "perl.h" + #include "XSUB.h" + + #include + + int + fputs(s, stream) + char * s + FILE * stream + +The real work is done in the standard typemap. + +B you lose all the fine stuff done by the perlio layers. This +calls the stdio function C, which knows nothing about them. + +The standard typemap offers three variants of PerlIO *: +C (T_IN), C (T_INOUT) and C +(T_OUT). A bare C is considered a T_INOUT. If it matters +in your code (see below for why it might) #define or typedef +one of the specific names and use that as the argument or result +type in your XS file. + +The standard typemap does not contain PerlIO * before perl 5.7, +but it has the three stream variants. Using a PerlIO * directly +is not backwards compatible unless you provide your own typemap. + +For streams coming I perl the main difference is that +C will get the output PerlIO * - which may make +a difference on a socket. Like in our example... + +For streams being handed I perl a new file handle is created +(i.e. a reference to a new glob) and associated with the PerlIO * +provided. If the read/write state of the PerlIO * is not correct then you +may get errors or warnings from when the file handle is used. +So if you opened the PerlIO * as "w" it should really be an +C if open as "r" it should be an C. + +Now, suppose you want to use perlio layers in your XS. We'll use the +perlio C function as an example. + +In the C part of the XS file (above the first MODULE line) you +have + + #define OutputStream PerlIO * + or + typedef PerlIO * OutputStream; + + +And this is the XS code: + + int + perlioputs(s, stream) + char * s + OutputStream stream + CODE: + RETVAL = PerlIO_puts(stream, s); + OUTPUT: + RETVAL + +We have to use a C section because C has the arguments +reversed compared to C, and we want to keep the arguments the same. + +Wanting to explore this thoroughly, we want to use the stdio C +on a PerlIO *. This means we have to ask the perlio system for a stdio +C: + + int + perliofputs(s, stream) + char * s + OutputStream stream + PREINIT: + FILE *fp = PerlIO_findFILE(stream); + CODE: + if (fp != (FILE*) 0) { + RETVAL = fputs(s, fp); + } else { + RETVAL = -1; + } + OUTPUT: + RETVAL + +Note: C will search the layers for a stdio +layer. If it can't find one, it will call C to +generate a new stdio C. Please only call C if +you want a I C. It will generate one on each call and push a +new stdio layer. So don't call it repeatedly on the same +file. C will retrieve the stdio layer once it has been +generated by C. + +This applies to the perlio system only. For versions before 5.7, +C is equivalent to C. + +=head2 Troubleshooting these Examples + +As mentioned at the top of this document, if you are having problems with +these example extensions, you might see if any of these help you. + +=over 4 + +=item * + +In versions of 5.002 prior to the gamma version, the test script in Example +1 will not function properly. You need to change the "use lib" line to +read: + + use lib './blib'; + +=item * + +In versions of 5.002 prior to version 5.002b1h, the test.pl file was not +automatically created by h2xs. This means that you cannot say "make test" +to run the test script. You will need to add the following line before the +"use extension" statement: + + use lib './blib'; + +=item * + +In versions 5.000 and 5.001, instead of using the above line, you will need +to use the following line: + + BEGIN { unshift(@INC, "./blib") } + +=item * + +This document assumes that the executable named "perl" is Perl version 5. +Some systems may have installed Perl version 5 as "perl5". + +=back + +=head1 See also + +For more information, consult L, L, L, L, +and L. + +=head1 Author + +Jeff Okamoto > + +Reviewed and assisted by Dean Roehrich, Ilya Zakharevich, Andreas Koenig, +and Tim Bunce. + +PerlIO material contributed by Lupe Christoph, with some clarification +by Nick Ing-Simmons. + +Changes for h2xs as of Perl 5.8.x by Renee Baecker + +=head2 Last Changed + +2012-01-20 diff --git a/lib/perlxstypemap.pod b/lib/perlxstypemap.pod new file mode 100644 index 0000000..7d1f73c --- /dev/null +++ b/lib/perlxstypemap.pod @@ -0,0 +1,711 @@ +=head1 NAME + +perlxstypemap - Perl XS C/Perl type mapping + +=head1 DESCRIPTION + +The more you think about interfacing between two languages, the more +you'll realize that the majority of programmer effort has to go into +converting between the data structures that are native to either of +the languages involved. This trumps other matter such as differing +calling conventions because the problem space is so much greater. +There are simply more ways to shove data into memory than there are +ways to implement a function call. + +Perl XS' attempt at a solution to this is the concept of typemaps. +At an abstract level, a Perl XS typemap is nothing but a recipe for +converting from a certain Perl data structure to a certain C +data structure and vice versa. Since there can be C types that +are sufficiently similar to one another to warrant converting with +the same logic, XS typemaps are represented by a unique identifier, +henceforth called an B in this document. You can then tell +the XS compiler that multiple C types are to be mapped with the same +XS typemap. + +In your XS code, when you define an argument with a C type or when +you are using a C and an C section together with a +C return type of your XSUB, it'll be the typemapping mechanism that +makes this easy. + +=head2 Anatomy of a typemap + +In more practical terms, the typemap is a collection of code +fragments which are used by the B compiler to map C function +parameters and values to Perl values. The typemap file may consist +of three sections labelled C, C, and C. +An unlabelled initial section is assumed to be a C 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, C, or +C must begin in the first column on a line by themselves, +and must be in uppercase. + +Each type of section can appear an arbitrary number of times +and does not have to appear at all. For example, a typemap may +commonly lack C and C sections if all it needs to +do is associate additional C types with core XS types like T_PTROBJ. +Lines that start with a hash C<#> are considered comments and ignored +in the C section, but are considered significant in C +and C. Blank lines are generally ignored. + +Traditionally, typemaps needed to be written to a separate file, +conventionally called C in a CPAN distribution. With +ExtUtils::ParseXS (the XS compiler) version 3.12 or better which +comes with perl 5.16, typemaps can also be embedded directly into +XS code using a HERE-doc like syntax: + + TYPEMAP: < can be replaced by other identifiers like with normal +Perl HERE-docs. All details below about the typemap textual format +remain valid. + +The C section should contain one pair of C type and +XS type per line as follows. An example from the core typemap file: + + TYPEMAP + # all variants of char* is handled by the T_PV typemap + char * T_PV + const char * T_PV + unsigned char * T_PV + ... + +The C and C sections have identical formats, that is, +each unindented line starts a new in- or output map respectively. +A new in- or output map must start with the name of the XS type to +map on a line by itself, followed by the code that implements it +indented on the following lines. Example: + + INPUT + T_PV + $var = ($type)SvPV_nolen($arg) + T_PTR + $var = INT2PTR($type,SvIV($arg)) + +We'll get to the meaning of those Perlish-looking variables in a +little bit. + +Finally, here's an example of the full typemap file for mapping C +strings of the C type to Perl scalars/strings: + + TYPEMAP + char * T_PV + + INPUT + T_PV + $var = ($type)SvPV_nolen($arg) + + OUTPUT + T_PV + sv_setpv((SV*)$arg, $var); + +Here's a more complicated example: suppose that you wanted +C to be blessed into the class C. +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 that maps +underscores to double-colons (::), and declare C 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 = INT2PTR($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. + +The C 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 C, C, C macros, +to map the other way, which may be useful in OUTPUT sections. + +=head2 The Role of the typemap File in Your Distribution + +The default typemap in the F 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 compiler will allow the extension's own typemap to +override any mappings which are in the default typemap. Instead of using +an additional F file, typemaps may be embedded verbatim in XS +with a heredoc-like syntax. See the documentation on the C XS +keyword. + +For CPAN distributions, you can assume that the XS types defined by +the perl core are already available. Additionally, the core typemap +has default XS types for a large number of C types. For example, if +you simply return a C from your XSUB, the core typemap will +have this C type associated with the T_PV XS type. That means your +C string will be copied into the PV (pointer value) slot of a new scalar +that will be returned from your XSUB to Perl. + +If you're developing a CPAN distribution using XS, you may add your own +file called F to the distribution. That file may contain +typemaps that either map types that are specific to your code or that +override the core typemap file's mappings for common C types. + +=head2 Sharing typemaps Between CPAN Distributions + +Starting with ExtUtils::ParseXS version 3.13_01 (comes with perl 5.16 +and better), it is rather easy to share typemap code between multiple +CPAN distributions. The general idea is to share it as a module that +offers a certain API and have the dependent modules declare that as a +built-time requirement and import the typemap into the XS. An example +of such a typemap-sharing module on CPAN is +C. Two steps to getting that module's +typemaps available in your code: + +=over 4 + +=item * + +Declare C as a build-time dependency +in C (use C), or in your C +(use C). + +=item * + +Include the following line in the XS section of your XS file: +(don't break the line) + + INCLUDE_COMMAND: $^X -MExtUtils::Typemaps::Cmd + -e "print embeddable_typemap(q{Basic})" + +=back + +=head2 Writing typemap Entries + +Each INPUT or OUTPUT typemap entry is a double-quoted Perl string that +will be evaluated in the presence of certain variables to get the +final C code for mapping a certain C type. + +This means that you can embed Perl code in your typemap (C) code using +constructs such as +C<${ perl code that evaluates to scalar reference here }>. A common +use case is to generate error messages that refer to the true function +name even when using the ALIAS XS feature: + + ${ $ALIAS ? \q[GvNAME(CvGV(cv))] : \qq[\"$pname\"] } + +For many typemap examples, refer to the core typemap file that can be +found in the perl source tree at F. + +The Perl variables that are available for interpolation into typemaps +are the following: + +=over 4 + +=item * + +I<$var> - the name of the input or output variable, eg. RETVAL for +return values. + +=item * + +I<$type> - the raw C type of the parameter, any C<:> replaced with +C<_>. +e.g. for a type of C, I<$type> is C + +=item * + +I<$ntype> - the supplied type with C<*> replaced with C. +e.g. for a type of C, I<$ntype> is C + +=item * + +I<$arg> - the stack entry, that the parameter is input from or output +to, e.g. C + +=item * + +I<$argoff> - the argument stack offset of the argument. ie. 0 for the +first argument, etc. + +=item * + +I<$pname> - the full name of the XSUB, with including the C +name, with any C stripped. This is the non-ALIAS name. + +=item * + +I<$Package> - the package specified by the most recent C +keyword. + +=item * + +I<$ALIAS> - non-zero if the current XSUB has any aliases declared with +C. + +=back + +=head2 Full Listing of Core Typemaps + +Each C type is represented by an entry in the typemap file that +is responsible for converting perl variables (SV, AV, HV, CV, etc.) +to and from that type. The following sections list all XS types +that come with perl by default. + +=over 4 + +=item T_SV + +This simply passes the C representation of the Perl variable (an SV*) +in and out of the XS layer. This can be used if the C code wants +to deal directly with the Perl variable. + +=item T_SVREF + +Used to pass in and return a reference to an SV. + +Note that this typemap does not decrement the reference count +when returning the reference to an SV*. +See also: T_SVREF_REFCOUNT_FIXED + +=item T_SVREF_FIXED + +Used to pass in and return a reference to an SV. +This is a fixed +variant of T_SVREF that decrements the refcount appropriately +when returning a reference to an SV*. Introduced in perl 5.15.4. + +=item T_AVREF + +From the perl level this is a reference to a perl array. +From the C level this is a pointer to an AV. + +Note that this typemap does not decrement the reference count +when returning an AV*. See also: T_AVREF_REFCOUNT_FIXED + +=item T_AVREF_REFCOUNT_FIXED + +From the perl level this is a reference to a perl array. +From the C level this is a pointer to an AV. This is a fixed +variant of T_AVREF that decrements the refcount appropriately +when returning an AV*. Introduced in perl 5.15.4. + +=item T_HVREF + +From the perl level this is a reference to a perl hash. +From the C level this is a pointer to an HV. + +Note that this typemap does not decrement the reference count +when returning an HV*. See also: T_HVREF_REFCOUNT_FIXED + +=item T_HVREF_REFCOUNT_FIXED + +From the perl level this is a reference to a perl hash. +From the C level this is a pointer to an HV. This is a fixed +variant of T_HVREF that decrements the refcount appropriately +when returning an HV*. Introduced in perl 5.15.4. + +=item T_CVREF + +From the perl level this is a reference to a perl subroutine +(e.g. $sub = sub { 1 };). From the C level this is a pointer +to a CV. + +Note that this typemap does not decrement the reference count +when returning an HV*. See also: T_HVREF_REFCOUNT_FIXED + +=item T_CVREF_REFCOUNT_FIXED + +From the perl level this is a reference to a perl subroutine +(e.g. $sub = sub { 1 };). From the C level this is a pointer +to a CV. + +This is a fixed +variant of T_HVREF that decrements the refcount appropriately +when returning an HV*. Introduced in perl 5.15.4. + +=item T_SYSRET + +The T_SYSRET typemap is used to process return values from system calls. +It is only meaningful when passing values from C to perl (there is +no concept of passing a system return value from Perl to C). + +System calls return -1 on error (setting ERRNO with the reason) +and (usually) 0 on success. If the return value is -1 this typemap +returns C. If the return value is not -1, this typemap +translates a 0 (perl false) to "0 but true" (which +is perl true) or returns the value itself, to indicate that the +command succeeded. + +The L module makes extensive use of this type. + +=item T_UV + +An unsigned integer. + +=item T_IV + +A signed integer. This is cast to the required integer type when +passed to C and converted to an IV when passed back to Perl. + +=item T_INT + +A signed integer. This typemap converts the Perl value to a native +integer type (the C type on the current platform). When returning +the value to perl it is processed in the same way as for T_IV. + +Its behaviour is identical to using an C type in XS with T_IV. + +=item T_ENUM + +An enum value. Used to transfer an enum component +from C. There is no reason to pass an enum value to C since +it is stored as an IV inside perl. + +=item T_BOOL + +A boolean type. This can be used to pass true and false values to and +from C. + +=item T_U_INT + +This is for unsigned integers. It is equivalent to using T_UV +but explicitly casts the variable to type C. +The default type for C is T_UV. + +=item T_SHORT + +Short integers. This is equivalent to T_IV but explicitly casts +the return to type C. The default typemap for C +is T_IV. + +=item T_U_SHORT + +Unsigned short integers. This is equivalent to T_UV but explicitly +casts the return to type C. The default typemap for +C is T_UV. + +T_U_SHORT is used for type C in the standard typemap. + +=item T_LONG + +Long integers. This is equivalent to T_IV but explicitly casts +the return to type C. The default typemap for C +is T_IV. + +=item T_U_LONG + +Unsigned long integers. This is equivalent to T_UV but explicitly +casts the return to type C. The default typemap for +C is T_UV. + +T_U_LONG is used for type C in the standard typemap. + +=item T_CHAR + +Single 8-bit characters. + +=item T_U_CHAR + +An unsigned byte. + +=item T_FLOAT + +A floating point number. This typemap guarantees to return a variable +cast to a C. + +=item T_NV + +A Perl floating point number. Similar to T_IV and T_UV in that the +return type is cast to the requested numeric type rather than +to a specific type. + +=item T_DOUBLE + +A double precision floating point number. This typemap guarantees to +return a variable cast to a C. + +=item T_PV + +A string (char *). + +=item T_PTR + +A memory address (pointer). Typically associated with a C +type. + +=item T_PTRREF + +Similar to T_PTR except that the pointer is stored in a scalar and the +reference to that scalar is returned to the caller. This can be used +to hide the actual pointer value from the programmer since it is usually +not required directly from within perl. + +The typemap checks that a scalar reference is passed from perl to XS. + +=item T_PTROBJ + +Similar to T_PTRREF except that the reference is blessed into a class. +This allows the pointer to be used as an object. Most commonly used to +deal with C structs. The typemap checks that the perl object passed +into the XS routine is of the correct class (or part of a subclass). + +The pointer is blessed into a class that is derived from the name +of type of the pointer but with all '*' in the name replaced with +'Ptr'. + +For C XSUBs only, a T_PTROBJ is optimized to a T_PTRREF. This means +the class check is skipped. + +=item T_REF_IV_REF + +NOT YET + +=item T_REF_IV_PTR + +Similar to T_PTROBJ in that the pointer is blessed into a scalar object. +The difference is that when the object is passed back into XS it must be +of the correct type (inheritance is not supported) while T_PTROBJ supports +inheritance. + +The pointer is blessed into a class that is derived from the name +of type of the pointer but with all '*' in the name replaced with +'Ptr'. + +For C XSUBs only, a T_REF_IV_PTR is optimized to a T_PTRREF. This +means the class check is skipped. + +=item T_PTRDESC + +NOT YET + +=item T_REFREF + +Similar to T_PTRREF, except the pointer stored in the referenced scalar +is dereferenced and copied to the output variable. This means that +T_REFREF is to T_PTRREF as T_OPAQUE is to T_OPAQUEPTR. All clear? + +Only the INPUT part of this is implemented (Perl to XSUB) and there +are no known users in core or on CPAN. + +=item T_REFOBJ + +Like T_REFREF, except it does strict type checking (inheritance is not +supported). + +For C XSUBs only, a T_REFOBJ is optimized to a T_REFREF. This means +the class check is skipped. + +=item T_OPAQUEPTR + +This can be used to store bytes in the string component of the +SV. Here the representation of the data is irrelevant to perl and the +bytes themselves are just stored in the SV. It is assumed that the C +variable is a pointer (the bytes are copied from that memory +location). If the pointer is pointing to something that is +represented by 8 bytes then those 8 bytes are stored in the SV (and +length() will report a value of 8). This entry is similar to T_OPAQUE. + +In principle the unpack() command can be used to convert the bytes +back to a number (if the underlying type is known to be a number). + +This entry can be used to store a C structure (the number +of bytes to be copied is calculated using the C C function) +and can be used as an alternative to T_PTRREF without having to worry +about a memory leak (since Perl will clean up the SV). + +=item T_OPAQUE + +This can be used to store data from non-pointer types in the string +part of an SV. It is similar to T_OPAQUEPTR except that the +typemap retrieves the pointer directly rather than assuming it +is being supplied. For example, if an integer is imported into +Perl using T_OPAQUE rather than T_IV the underlying bytes representing +the integer will be stored in the SV but the actual integer value will +not be available. i.e. The data is opaque to perl. + +The data may be retrieved using the C function if the +underlying type of the byte stream is known. + +T_OPAQUE supports input and output of simple types. +T_OPAQUEPTR can be used to pass these bytes back into C if a pointer +is acceptable. + +=item Implicit array + +xsubpp supports a special syntax for returning +packed C arrays to perl. If the XS return type is given as + + array(type, nelem) + +xsubpp will copy the contents of C bytes from +RETVAL to an SV and push it onto the stack. This is only really useful +if the number of items to be returned is known at compile time and you +don't mind having a string of bytes in your SV. Use T_ARRAY to push a +variable number of arguments onto the return stack (they won't be +packed as a single string though). + +This is similar to using T_OPAQUEPTR but can be used to process more +than one element. + +=item T_PACKED + +Calls user-supplied functions for conversion. For C +(XSUB to Perl), a function named C is called +with the output Perl scalar and the C variable to convert from. +C<$ntype> is the normalized C type that is to be mapped to +Perl. Normalized means that all C<*> are replaced by the +string C. The return value of the function is ignored. + +Conversely for C (Perl to XSUB) mapping, the +function named C is called with the input Perl +scalar as argument and the return value is cast to the mapped +C type and assigned to the output C variable. + +An example conversion function for a typemapped struct +C might be: + + static void + XS_pack_foo_tPtr(SV *out, foo_t *in) + { + dTHX; /* alas, signature does not include pTHX_ */ + HV* hash = newHV(); + hv_stores(hash, "int_member", newSViv(in->int_member)); + hv_stores(hash, "float_member", newSVnv(in->float_member)); + /* ... */ + + /* mortalize as thy stack is not refcounted */ + sv_setsv(out, sv_2mortal(newRV_noinc((SV*)hash))); + } + +The conversion from Perl to C is left as an exercise to the reader, +but the prototype would be: + + static foo_t * + XS_unpack_foo_tPtr(SV *in); + +Instead of an actual C function that has to fetch the thread context +using C, you can define macros of the same name and avoid the +overhead. Also, keep in mind to possibly free the memory allocated by +C. + +=item T_PACKEDARRAY + +T_PACKEDARRAY is similar to T_PACKED. In fact, the C (Perl +to XSUB) typemap is identical, but the C typemap passes +an additional argument to the C function. This +third parameter indicates the number of elements in the output +so that the function can handle C arrays sanely. The variable +needs to be declared by the user and must have the name +C where C<$ntype> is the normalized C type name +as explained above. The signature of the function would be for +the example above and C: + + static void + XS_pack_foo_tPtrPtr(SV *out, foo_t *in, UV count_foo_tPtrPtr); + +The type of the third parameter is arbitrary as far as the typemap +is concerned. It just has to be in line with the declared variable. + +Of course, unless you know the number of elements in the +C C array, within your XSUB, the return value from +C will be hard to decipher. +Since the details are all up to the XS author (the typemap user), +there are several solutions, none of which particularly elegant. +The most commonly seen solution has been to allocate memory for +N+1 pointers and assign C to the (N+1)th to facilitate +iteration. + +Alternatively, using a customized typemap for your purposes in +the first place is probably preferable. + +=item T_DATAUNIT + +NOT YET + +=item T_CALLBACK + +NOT YET + +=item T_ARRAY + +This is used to convert the perl argument list to a C array +and for pushing the contents of a C array onto the perl +argument stack. + +The usual calling signature is + + @out = array_func( @in ); + +Any number of arguments can occur in the list before the array but +the input and output arrays must be the last elements in the list. + +When used to pass a perl list to C the XS writer must provide a +function (named after the array type but with 'Ptr' substituted for +'*') to allocate the memory required to hold the list. A pointer +should be returned. It is up to the XS writer to free the memory on +exit from the function. The variable C is set to the number +of elements in the new array. + +When returning a C array to Perl the XS writer must provide an integer +variable called C containing the number of elements in the +array. This is used to determine how many elements should be pushed +onto the return argument stack. This is not required on input since +Perl knows how many arguments are on the stack when the routine is +called. Ordinarily this variable would be called C. + +Additionally, the type of each element is determined from the type of +the array. If the array uses type C xsubpp will +automatically work out that it contains variables of type C and +use that typemap entry to perform the copy of each element. All +pointer '*' and 'Array' tags are removed from the name to determine +the subtype. + +=item T_STDIO + +This is used for passing perl filehandles to and from C using +C structures. + +=item T_INOUT + +This is used for passing perl filehandles to and from C using +C structures. The file handle can used for reading and +writing. This corresponds to the C<+E> mode, see also T_IN +and T_OUT. + +See L for more information on the Perl IO abstraction +layer. Perl must have been built with C<-Duseperlio>. + +There is no check to assert that the filehandle passed from Perl +to C was created with the right C mode. + +Hint: The L tutorial covers the T_INOUT, T_IN, and T_OUT +XS types nicely. + +=item T_IN + +Same as T_INOUT, but the filehandle that is returned from C to Perl +can only be used for reading (mode C>). + +=item T_OUT + +Same as T_INOUT, but the filehandle that is returned from C to Perl +is set to use the open mode C<+E>. + +=back + diff --git a/t/XSTest.xs b/t/XSTest.xs index 89df22f..452d3db 100644 --- a/t/XSTest.xs +++ b/t/XSTest.xs @@ -76,6 +76,7 @@ bool T_BOOL_2(in) bool in CODE: + PERL_UNUSED_VAR(RETVAL); OUTPUT: in void diff --git a/t/XSUsage.xs b/t/XSUsage.xs index 9a8d93d..ed3c8f8 100644 --- a/t/XSUsage.xs +++ b/t/XSUsage.xs @@ -35,6 +35,8 @@ xsusage_two() ALIAS: two_x = 1 FOO::two = 2 + INIT: + PERL_UNUSED_VAR(ix); int interface_v_i() -- 2.14.3