summaryrefslogtreecommitdiff
path: root/pod/perlxs.pod
diff options
context:
space:
mode:
Diffstat (limited to 'pod/perlxs.pod')
-rw-r--r--pod/perlxs.pod986
1 files changed, 986 insertions, 0 deletions
diff --git a/pod/perlxs.pod b/pod/perlxs.pod
new file mode 100644
index 0000000000..ffbaa6b1c3
--- /dev/null
+++ b/pod/perlxs.pod
@@ -0,0 +1,986 @@
+=head1 NAME
+
+perlxs - XS language reference manual
+
+=head1 DESCRIPTION
+
+=head2 Introduction
+
+XS is a language used to create an extension interface
+between Perl and some C library which one wishes to use with
+Perl. The XS interface is combined with the library to
+create a new library which can be linked to Perl. An B<XSUB>
+is a function in the XS language and is the core component
+of the Perl application interface.
+
+The XS compiler is called B<xsubpp>. This compiler will embed
+the constructs necessary to let an XSUB, which is really a C
+function in disguise, manipulate Perl values and creates the
+glue necessary to let Perl access the XSUB. The compiler
+uses B<typemaps> to determine how to map C function parameters
+and variables to Perl values. The default typemap handles
+many common C types. A supplement typemap must be created
+to handle special structures and types for the library being
+linked.
+
+=head2 Getting Started
+
+A new extension should begin with the B<h2xs> tool. This will generate
+templates for the new Perl module (PM), the XS source file (XS), the MANIFEST
+file, and the Makefile.PL (PL) files. The Makefile.PL file is a Perl script
+which will generate a Makefile. This makefile knows how to find and run
+xsubpp for your extension. When you type "make" your XS file will be run
+through xsubpp and a C file will be produced. Then the C file will be
+compiled. A simple example looks like this for an example module named
+B<Foo>:
+
+ $ h2xs -Afn Foo
+ $ cd ext/Foo
+ $ ls
+ Foo.pm Foo.xs MANIFEST Makefile.PL
+ $ perl5 Makefile.PL
+ $ ls
+ Foo.pm Foo.xs MANIFEST Makefile.PL Makefile
+ $ <edit Foo.pm and Foo.xs to add your stuff>
+ $ make
+ <you will see xsubpp run on Foo.xs and you'll see the C compiler
+ <run on Foo.c, and a bunch of other less-interesting things
+ <will happen.
+
+If your Perl was built with dynamic loading then the makefile will build a
+dynamically loadable extension. If you don't have dynamic loading then the
+makefile will build a static extension and should create a new Perl binary.
+The default behavior depends on what is available.
+
+For more information about h2xs consult its manpage, embedded in the
+source. For information about the Makefile.PL and Makefile consult the
+MakeMaker manpage.
+
+=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.
+Specifically, the rpcb_gettime() function will be used to demonstrate many
+features of the XS language. This function has two parameters; the first
+is an input parameter and the second is an output parameter. The function
+also returns a status value.
+
+ bool_t rpcb_gettime(const char *host, time_t *timep);
+
+From C this function will be called with the following
+statements.
+
+ #include <rpc/rpc.h>
+ bool_t status;
+ time_t timep;
+ status = rpcb_gettime( "localhost", &timep );
+
+If an XSUB is created to offer a direct translation between this function
+and Perl, then this XSUB will be used from Perl with the following code.
+The $status and $timep variables will contain the output of the function.
+
+ use RPC;
+ $status = rpcb_gettime( "localhost", $timep );
+
+The following XS file shows an XS subroutine, or XSUB, which
+demonstrates one possible interface to the rpcb_gettime()
+function. This XSUB represents a direct translation between
+C and Perl and so preserves the interface even from Perl.
+This XSUB will be invoked from Perl with the usage shown
+above. Note that the first three #include statements, for
+C<EXTERN.h>, C<perl.h>, and C<XSUB.h>, will always be present at the
+beginning of an XS file. This approach and others will be
+expanded later in this document.
+
+ #include "EXTERN.h"
+ #include "perl.h"
+ #include "XSUB.h"
+ #include <rpc/rpc.h>
+
+ MODULE = RPC PACKAGE = RPC
+
+ bool_t
+ rpcb_gettime(host,timep)
+ char *host
+ time_t &timep
+ OUTPUT:
+ timep
+
+Any extension to Perl, including those containing XSUBs,
+should have a Perl module to serve as the bootstrap which
+pulls the extension into Perl. This module will export the
+extension's functions and variables to the Perl program and
+will cause the extension's XSUBs to be linked into Perl.
+The following module will be used for most of the examples
+in this document and should be used from Perl with the C<use>
+command as shown earlier. Perl modules are explained in
+more detail later in this document.
+
+ package RPC;
+
+ require Exporter;
+ require DynaLoader;
+ @ISA = qw(Exporter DynaLoader);
+ @EXPORT = qw( rpcb_gettime );
+
+ bootstrap RPC;
+ 1;
+
+Throughout this document a variety of interfaces to the rpcb_gettime()
+XSUB will be explored. The XSUBs will take their parameters in different
+orders or will take different numbers of parameters. In each case the
+XSUB is an abstraction between Perl and the real C rpcb_gettime()
+function, and the XSUB must always ensure that the real rpcb_gettime()
+function is called with the correct parameters. This abstraction will
+allow the programmer to create a more Perl-like interface to the C
+function.
+
+=head2 The Anatomy of an XSUB
+
+The following XSUB allows a Perl program to access a C library function
+called sin(). The XSUB will imitate the C function which takes a single
+argument and returns a single value.
+
+ double
+ sin(x)
+ double x
+
+When using C pointers the indirection operator C<*> should be considered
+part of the type and the address operator C<&> should be considered part of
+the variable, as is demonstrated in the rpcb_gettime() function above. See
+the section on typemaps for more about handling qualifiers and unary
+operators in C types.
+
+The parameter list of a function must not have whitespace after the
+open-parenthesis or before the close-parenthesis. (This restriction will be
+relaxed in later versions of B<xsubpp>.)
+
+ INCORRECT CORRECT
+
+ double double
+ sin( x ) sin(x)
+ double x double x
+
+The function name and the return type must be placed on
+separate lines.
+
+ INCORRECT CORRECT
+
+ double sin(x) double
+ double x sin(x)
+ double x
+
+=head2 The Argument Stack
+
+The argument stack is used to store the values which are
+sent as parameters to the XSUB and to store the XSUB's
+return value. In reality all Perl functions keep their
+values on this stack at the same time, each limited to its
+own range of positions on the stack. In this document the
+first position on that stack which belongs to the active
+function will be referred to as position 0 for that function.
+
+XSUBs refer to their stack arguments with the macro B<ST(x)>, where I<x>
+refers to a position in this XSUB's part of the stack. Position 0 for that
+function would be known to the XSUB as ST(0). The XSUB's incoming
+parameters and outgoing return values always begin at ST(0). For many
+simple cases the B<xsubpp> compiler will generate the code necessary to
+handle the argument stack by embedding code fragments found in the
+typemaps. In more complex cases the programmer must supply the code.
+
+=head2 The RETVAL Variable
+
+The RETVAL variable is a magic variable which always matches
+the return type of the C library function. The B<xsubpp> compiler will
+supply this variable in each XSUB and by default will use it to hold the
+return value of the C library function being called. In simple cases the
+value of RETVAL will be placed in ST(0) of the argument stack where it can
+be received by Perl as the return value of the XSUB.
+
+If the XSUB has a return type of C<void> then the compiler will
+not supply a RETVAL variable for that function. When using
+the PPCODE: directive the RETVAL variable may not be needed.
+
+=head2 The MODULE Keyword
+
+The MODULE keyword is used to start the XS code and to
+specify the package of the functions which are being
+defined. All text preceding the first MODULE keyword is
+considered C code and is passed through to the output
+untouched. Every XS module will have a bootstrap function
+which is used to hook the XSUBs into Perl. The package name
+of this bootstrap function will match the value of the last
+MODULE statement in the XS source files. The value of
+MODULE should always remain constant within the same XS
+file, though this is not required.
+
+The following example will start the XS code and will place
+all functions in a package named RPC.
+
+ MODULE = RPC
+
+=head2 The PACKAGE Keyword
+
+When functions within an XS source file must be separated into packages
+the PACKAGE keyword should be used. This keyword is used with the MODULE
+keyword and must follow immediately after it when used.
+
+ MODULE = RPC PACKAGE = RPC
+
+ [ XS code in package RPC ]
+
+ MODULE = RPC PACKAGE = RPCB
+
+ [ XS code in package RPCB ]
+
+ MODULE = RPC PACKAGE = RPC
+
+ [ XS code in package RPC ]
+
+Although this keyword is optional and in some cases provides redundant
+information it should always be used. This keyword will ensure that the
+XSUBs appear in the desired package.
+
+=head2 The PREFIX Keyword
+
+The PREFIX keyword designates prefixes which should be
+removed from the Perl function names. If the C function is
+C<rpcb_gettime()> and the PREFIX value is C<rpcb_> then Perl will
+see this function as C<gettime()>.
+
+This keyword should follow the PACKAGE keyword when used.
+If PACKAGE is not used then PREFIX should follow the MODULE
+keyword.
+
+ MODULE = RPC PREFIX = rpc_
+
+ MODULE = RPC PACKAGE = RPCB PREFIX = rpcb_
+
+=head2 The OUTPUT: Keyword
+
+The OUTPUT: keyword indicates that certain function parameters should be
+updated (new values made visible to Perl) when the XSUB terminates or that
+certain values should be returned to the calling Perl function. For
+simple functions, such as the sin() function above, the RETVAL variable is
+automatically designated as an output value. In more complex functions
+the B<xsubpp> compiler will need help to determine which variables are output
+variables.
+
+This keyword will normally be used to complement the CODE: keyword.
+The RETVAL variable is not recognized as an output variable when the
+CODE: keyword is present. The OUTPUT: keyword is used in this
+situation to tell the compiler that RETVAL really is an output
+variable.
+
+The OUTPUT: keyword can also be used to indicate that function parameters
+are output variables. This may be necessary when a parameter has been
+modified within the function and the programmer would like the update to
+be seen by Perl.
+
+ bool_t
+ rpcb_gettime(host,timep)
+ char *host
+ time_t &timep
+ OUTPUT:
+ timep
+
+The OUTPUT: keyword will also allow an output parameter to
+be mapped to a matching piece of code rather than to a
+typemap.
+
+ bool_t
+ rpcb_gettime(host,timep)
+ char *host
+ time_t &timep
+ OUTPUT:
+ timep sv_setnv(ST(1), (double)timep);
+
+=head2 The CODE: Keyword
+
+This keyword is used in more complicated XSUBs which require
+special handling for the C function. The RETVAL variable is
+available but will not be returned unless it is specified
+under the OUTPUT: keyword.
+
+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
+
+In many of the examples shown here the CODE: block (and
+other blocks) will often be contained within braces ( C<{> and
+C<}> ). This protects the CODE: block from complex INPUT
+typemaps and ensures the resulting C code is legal.
+
+=head2 The NO_INIT Keyword
+
+The NO_INIT keyword is used to indicate that a function
+parameter is being used as only an output value. The B<xsubpp>
+compiler will normally generate code to read the values of
+all function parameters from the argument stack and assign
+them to C variables upon entry to the function. NO_INIT
+will tell the compiler that some parameters will be used for
+output rather than for input and that they will be handled
+before the function terminates.
+
+The following example shows a variation of the rpcb_gettime() function.
+This function uses the timep variable as only an output variable and does
+not care about its initial contents.
+
+ bool_t
+ rpcb_gettime(host,timep)
+ char *host
+ time_t &timep = NO_INIT
+ OUTPUT:
+ timep
+
+=head2 Initializing Function Parameters
+
+Function parameters are normally initialized with their
+values from the argument stack. The typemaps contain the
+code segments which are used to transfer the Perl values to
+the C parameters. The programmer, however, is allowed to
+override the typemaps and supply alternate initialization
+code.
+
+The following code demonstrates how to supply initialization code for
+function parameters. The initialization code is eval'd by the compiler
+before it is added to the output so anything which should be interpreted
+literally, such as double quotes, must be protected with backslashes.
+
+ bool_t
+ rpcb_gettime(host,timep)
+ char *host = (char *)SvPV(ST(0),na);
+ time_t &timep = 0;
+ OUTPUT:
+ timep
+
+This should not be used to supply default values for parameters. One
+would normally use this when a function parameter must be processed by
+another library function before it can be used. Default parameters are
+covered in the next section.
+
+=head2 Default Parameter Values
+
+Default values can be specified for function parameters by
+placing an assignment statement in the parameter list. The
+default value may be a number or a string. 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. Perl will call this
+XSUB 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 Variable-length Parameter Lists
+
+XSUBs can have variable-length parameter lists by specifying an ellipsis
+C<(...)> in the parameter list. This use of the ellipsis is similar to that
+found in ANSI C. The programmer is able to determine the number of
+arguments passed to the XSUB by examining the C<items> variable which the
+B<xsubpp> compiler supplies for all XSUBs. By using this mechanism one can
+create an XSUB which accepts a list of parameters of unknown length.
+
+The I<host> parameter for the rpcb_gettime() XSUB can be
+optional so the ellipsis can be used to indicate that the
+XSUB will take a variable number of parameters. Perl should
+be able to call this XSUB with either of the following statements.
+
+ $status = rpcb_gettime( $timep, $host );
+
+ $status = rpcb_gettime( $timep );
+
+The XS code, with ellipsis, follows.
+
+ bool_t
+ rpcb_gettime(timep, ...)
+ time_t timep = NO_INIT
+ CODE:
+ {
+ char *host = "localhost";
+
+ if( items > 1 )
+ host = (char *)SvPV(ST(1), na);
+ RETVAL = rpcb_gettime( host, &timep );
+ }
+ OUTPUT:
+ timep
+ RETVAL
+
+=head2 The PPCODE: Keyword
+
+The PPCODE: keyword is an alternate form of the CODE: keyword and is used
+to tell the B<xsubpp> compiler that the programmer is supplying the code to
+control the argument stack for the XSUBs return values. Occasionally one
+will want an XSUB to return a list of values rather than a single value.
+In these cases one must use PPCODE: and then explicitly push the list of
+values on the stack. The PPCODE: and CODE: keywords are not used
+together within the same XSUB.
+
+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
+ PPCODE:
+ {
+ time_t timep;
+ bool_t status;
+ status = rpcb_gettime( host, &timep );
+ EXTEND(sp, 2);
+ PUSHs(sv_2mortal(newSVnv(status)));
+ PUSHs(sv_2mortal(newSVnv(timep)));
+ }
+
+Notice that the programmer must supply the C code necessary
+to have the real rpcb_gettime() function called and to have
+the return values properly placed on the argument stack.
+
+The C<void> return type for this function tells the B<xsubpp> compiler that
+the RETVAL variable is not needed or used and that it should not be created.
+In most scenarios the void return type should be used with the PPCODE:
+directive.
+
+The EXTEND() macro is used to make room on the argument
+stack for 2 return values. The PPCODE: directive causes the
+B<xsubpp> compiler to create a stack pointer called C<sp>, and it
+is this pointer which is being used in the EXTEND() macro.
+The values are then pushed onto the stack with the PUSHs()
+macro.
+
+Now the rpcb_gettime() function can be used from Perl with
+the following statement.
+
+ ($status, $timep) = rpcb_gettime("localhost");
+
+=head2 Returning Undef And Empty Lists
+
+Occasionally the programmer will want to simply return
+C<undef> or an empty list if a function fails rather than a
+separate status value. The rpcb_gettime() function offers
+just this situation. If the function succeeds we would like
+to have it return the time and if it fails we would like to
+have undef returned. In the following Perl code the value
+of $timep will either be undef or it will be a valid time.
+
+ $timep = rpcb_gettime( "localhost" );
+
+The following XSUB uses the C<void> return type to disable the generation of
+the RETVAL variable 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.
+
+ void
+ rpcb_gettime(host)
+ char * host
+ CODE:
+ {
+ time_t timep;
+ bool_t x;
+ 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.
+
+ void
+ rpcb_gettime(host)
+ char * host
+ CODE:
+ {
+ time_t timep;
+ bool_t x;
+ ST(0) = sv_newmortal();
+ if( rpcb_gettime( host, &timep ) ){
+ sv_setnv( ST(0), (double)timep);
+ }
+ else{
+ ST(0) = &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
+ PPCODE:
+ {
+ time_t timep;
+ if( rpcb_gettime( host, &timep ) )
+ PUSHs(sv_2mortal(newSVnv(timep)));
+ else{
+ /* Nothing pushed on stack, so an empty */
+ /* list is implicitly returned. */
+ }
+ }
+
+=head2 The CLEANUP: Keyword
+
+This keyword can be used when an XSUB requires special cleanup procedures
+before it terminates. When the CLEANUP: keyword is used it must follow
+any CODE:, PPCODE:, or OUTPUT: blocks which are present in the XSUB. The
+code specified for the cleanup block will be added as the last statements
+in the XSUB.
+
+=head2 The BOOT: Keyword
+
+The BOOT: keyword is used to add code to the extension's bootstrap
+function. The bootstrap function is generated by the B<xsubpp> compiler and
+normally holds the statements necessary to register any XSUBs with Perl.
+With the BOOT: keyword the programmer can tell the compiler to add extra
+statements to the bootstrap function.
+
+This keyword may be used any time after the first MODULE keyword and should
+appear on a line by itself. The first blank line after the keyword will
+terminate the code block.
+
+ BOOT:
+ # The following message will be printed when the
+ # bootstrap function executes.
+ printf("Hello from the bootstrap!\n");
+
+=head2 Inserting Comments and C Preprocessor Directives
+
+Comments and C preprocessor directives are allowed within
+CODE:, PPCODE:, BOOT:, and CLEANUP: blocks. The compiler
+will pass the preprocessor directives through untouched and
+will remove the commented lines. Comments can be added to
+XSUBs by placing a C<#> at the beginning of the line. Care
+should be taken to avoid making the comment look like a C
+preprocessor directive, lest it be interpreted as such.
+
+=head2 Using XS With C++
+
+If a function is defined as a C++ method then it will assume
+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_setptrobj() macro. The
+blessing of the object by Perl can be handled by the
+T_PTROBJ typemap.
+
+If the method is defined as static 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->method() syntax.
+
+=head2 Perl Variables
+
+The following demonstrates how the Perl variable $host can
+be accessed from an XSUB. The function B<perl_get_sv()> is
+used to obtain a pointer to the variable, known as an B<SV>
+(Scalar Variable) internally. The package name C<RPC> will be
+added to the name of the variable so perl_get_sv() will know
+in which package $host can be found. If the package name is
+not supplied then perl_get_sv() will search package C<main> for
+the variable. The macro B<SvPVX()> is then used to dereference
+the SV to obtain a C<char*> pointer to its contents.
+
+ void
+ rpcb_gettime()
+ PPCODE:
+ {
+ char *host;
+ SV *hostsv;
+ time_t timep;
+
+ hostsv = perl_get_sv( "RPC::host", FALSE );
+ if( hostsv != NULL ){
+ host = SvPVX( hostsv );
+ if( rpcb_gettime( host, &timep ) )
+ PUSHs(sv_2mortal(newSVnv(timep)));
+ }
+ }
+
+This Perl code can be used to call that XSUB.
+
+ $RPC::host = "localhost";
+ $timep = rpcb_gettime();
+
+In the above example the SV contained a C C<char*> but a Perl
+scalar variable may also contain numbers and references. If
+the SV is expected to have a C C<int> then the macro B<SvIVX()>
+should be used to dereference the SV. When the SV contains
+a C double then B<SvNVX()> should be used.
+
+The macro B<SvRV()> can be used to dereference an SV when it is a Perl
+reference. The result will be another SV which points to the actual Perl
+variable. This can then be dereferenced with SvPVX(), SvNVX(), or
+SvIVX(). The following XSUB will use SvRV().
+
+ void
+ rpcb_gettime()
+ PPCODE:
+ {
+ char *host;
+ SV *rv;
+ SV *hostsv;
+ time_t timep;
+
+ rv = perl_get_sv( "RPC::host", FALSE );
+ if( rv != NULL ){
+ hostsv = SvRV( rv );
+ host = SvPVX( hostsv );
+ if( rpcb_gettime( host, &timep ) )
+ PUSHs(sv_2mortal(newSVnv(timep)));
+ }
+ }
+
+This Perl code will create a variable $RPC::host which is a
+reference to $MY::host. The variable $MY::host contains the
+hostname which will be used.
+
+ $MY::host = "localhost";
+ $RPC::host = \$MY::host;
+ $timep = rpcb_gettime();
+
+The second argument to perl_get_sv() will normally be B<FALSE>
+as shown in the above examples. An argument of B<TRUE> will
+cause variables to be created if they do not already exist.
+One should not use TRUE unless steps are taken to deal with
+a possibly empty SV.
+
+XSUBs may use B<perl_get_av()>, B<perl_get_hv()>, and B<perl_get_cv()> to
+access Perl arrays, hashes, and code values.
+
+=head2 Interface Strategy
+
+When designing an interface between Perl and a C library a straight
+translation from C to XS is often sufficient. The interface will often be
+very C-like and occasionally nonintuitive, especially when the C function
+modifies one of its parameters. 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 which modify their parameters. The XSUBs for
+these functions may be able to return lists to Perl, or may be
+candidates to return undef or an empty list in case of failure.
+
+Identify which values are used by only the C and XSUB functions
+themselves. 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 can be handled in XS with the & unary operator on
+the variable name while others will require the use of the * operator on
+the type name. In general it is easier to work with the & operator.
+
+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.
+
+=head2 The Perl Module
+
+The Perl module is the link between the extension library,
+which was generated from XS code, and the Perl interpreter.
+The module is used to tell Perl what the extension library
+contains. The name and package of the module should match
+the name of the library.
+
+The following is a Perl module for an extension containing
+some ONC+ RPC bind library functions.
+
+ package RPC;
+
+ require Exporter;
+ require DynaLoader;
+ @ISA = qw(Exporter DynaLoader);
+ @EXPORT = qw( rpcb_gettime rpcb_getmaps rpcb_getaddr
+ rpcb_rmtcall rpcb_set rpcb_unset );
+
+ bootstrap RPC;
+ 1;
+
+The RPC extension contains the functions found in the
+@EXPORT list. By using the C<Exporter> module the RPC module
+can make these function names visible to the rest of the
+Perl program. The C<DynaLoader> module will allow the RPC
+module to bootstrap the extension library. To load this
+extension and make the functions available, the following
+Perl statement should be used.
+
+ use RPC;
+
+For more information about the DynaLoader consult its documentation in the
+ext/DynaLoader directory in the Perl source.
+
+=head2 Perl Objects And C Structures
+
+When dealing with C structures one should select either
+B<T_PTROBJ> or B<T_PTRREF> for the XS type. Both types are
+designed to handle pointers to complex objects. The
+T_PTRREF type will allow the Perl object to be unblessed
+while the T_PTROBJ type requires that the object be blessed.
+By using T_PTROBJ one can achieve a form of type-checking
+because the XSUB will attempt to verify that the Perl object
+is of the expected type.
+
+The following XS code shows the getnetconfigent() function which is used
+with ONC+ TIRPC. The getnetconfigent() function will return a pointer to a
+C structure and has the C prototype shown below. The example will
+demonstrate how the C pointer will become a Perl reference. Perl will
+consider this reference to be a pointer to a blessed object and will
+attempt to call a destructor for the object. A destructor will be
+provided in the XS source to free the memory used by getnetconfigent().
+Destructors in XS can be created by specifying an XSUB function whose name
+ends with the word B<DESTROY>. XS destructors can be used to free memory
+which may have been malloc'd by another XSUB.
+
+ struct netconfig *getnetconfigent(const char *netid);
+
+A C<typedef> will be created for C<struct netconfig>. The Perl
+object will be blessed in a class matching the name of the C
+type, with the tag C<Ptr> appended, and the name should not
+have embedded spaces if it will be a Perl package name. The
+destructor will be placed in a class corresponding to the
+class of the object and the PREFIX keyword will be used to
+trim the name to the word DESTROY as Perl will expect.
+
+ typedef struct netconfig Netconfig;
+
+ MODULE = RPC PACKAGE = RPC
+
+ Netconfig *
+ getnetconfigent(netid)
+ char *netid
+
+ MODULE = RPC PACKAGE = NetconfigPtr PREFIX = rpcb_
+
+ void
+ rpcb_DESTROY(netconf)
+ Netconfig *netconf
+ CODE:
+ printf("Now in NetconfigPtr::DESTROY\n");
+ free( netconf );
+
+This example requires the following typemap entry. Consult the typemap
+section for more information about adding new typemaps for an extension.
+
+ TYPEMAP
+ Netconfig * T_PTROBJ
+
+This example will be used with the following Perl statements.
+
+ use RPC;
+ $netconf = getnetconfigent("udp");
+
+When Perl destroys the object referenced by $netconf it will send the
+object to the supplied XSUB DESTROY function. Perl cannot determine, and
+does not care, that this object is a C struct and not a Perl object. In
+this sense, there is no difference between the object created by the
+getnetconfigent() XSUB and an object created by a normal Perl subroutine.
+
+=head2 C Headers and Perl
+
+The B<h2xs> compiler is designed to convert C header files in
+/usr/include into Perl extensions. This compiler will
+create a directory under the C<ext> directory of the Perl
+source and will populate it with a Makefile, a Perl Module,
+an XS source file, and a MANIFEST file.
+
+The following command will create an extension called C<Rusers>
+from the <rpcsvc/rusers.h> header.
+
+ h2xs rpcsvc/rusers
+
+When the Rusers extension has been compiled and installed
+Perl can use it to retrieve any C<#define> statements which
+were in the C header.
+
+ use Rusers;
+ print "RPC program number for rusers service: ";
+ print &RUSERSPROG, "\n";
+
+=head2 Creating A New Extension
+
+The B<h2xs> compiler can generate template source files and
+Makefiles. These templates offer a suitable starting point
+for most extensions. The following example demonstrates how
+one might use B<h2xs> to create an extension containing the RPC
+functions in this document.
+
+The extension will not use autoloaded functions and will not define
+constants, so the B<-A> option will be given to B<h2xs>. When run from the
+Perl source directory, the B<h2xs> compiler will create the directory
+ext/RPC and will populate it with files called RPC.xs, RPC.pm, Makefile.PL,
+and MANIFEST. The XS code for the RPC functions should be added to the
+RPC.xs file. The @EXPORT list in RPC.pm should be updated to include the
+functions from RPC.xs.
+
+ h2xs -An RPC
+
+To compile the extension for dynamic loading the following
+command should be executed from the ext/RPC directory.
+
+ make dynamic
+
+If the extension will be statically linked into the Perl
+binary then the makefile (use C<makefile>, not C<Makefile>) in the
+Perl source directory should be edited to add C<ext/RPC/RPC.a>
+to the C<static_ext> variable. Before making this change Perl
+should have already been built. After the makefile has been
+updated the following command should be executed from the
+Perl source directory.
+
+ make
+
+Perl's B<Configure> script can also be used to add extensions. The extension
+should be placed in the C<ext> directory under the Perl source before Perl
+has been built and prior to running Configure. When Configure is run it
+will find the extension along with the other extensions in the C<ext>
+directory and will add it to the list of extensions to be built. When make
+is run the extension will be built along with the other extensions.
+
+Configure recognizes extensions if they have an XS source
+file which matches the name of the extension directory. If
+the extension directory includes a MANIFEST file Configure
+will search that file for any B<.SH> files and extract them
+after it extracts all the other .SH files listed in the main
+MANIFEST. The main Perl Makefile will then run B<make> in the
+extension's directory if it finds an XS file matching the
+name of the extension's directory.
+
+=head2 The Typemap
+
+The typemap is a collection of code fragments which are used by the B<xsubpp>
+compiler to map C function parameters and values to Perl values. The
+typemap file may consist of three sections labeled C<TYPEMAP>, C<INPUT>, and
+C<OUTPUT>. 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.
+Each of the sections of the typemap must be preceded by one of the TYPEMAP,
+INPUT, or OUTPUT keywords.
+
+The default typemap in the C<ext> directory of the Perl source contains many
+useful types which can be used by Perl extensions. Some extensions define
+additional typemaps which they keep in their own directory. These
+additional typemaps may reference INPUT and OUTPUT maps in the main
+typemap. The B<xsubpp> compiler will allow the extension's own typemap to
+override any mappings which are in the default typemap.
+
+Most extensions which require a custom typemap will need only the TYPEMAP
+section of the typemap file. The custom typemap used in the
+getnetconfigent() example shown earlier demonstrates what may be the typical
+use of extension typemaps. That typemap is used to equate a C structure
+with the T_PTROBJ typemap. The typemap used by getnetconfigent() is shown
+here. Note that the C type is separated from the XS type with a tab and
+that the C unary operator C<*> is considered to be a part of the C type name.
+
+ TYPEMAP
+ Netconfig *<tab>T_PTROBJ
+
+=head1 EXAMPLES
+
+File C<RPC.xs>: Interface to some ONC+ RPC bind library functions.
+
+ #include "EXTERN.h"
+ #include "perl.h"
+ #include "XSUB.h"
+
+ #include <rpc/rpc.h>
+
+ typedef struct netconfig Netconfig;
+
+ MODULE = RPC PACKAGE = RPC
+
+ void
+ rpcb_gettime(host="localhost")
+ char *host
+ CODE:
+ {
+ time_t timep;
+ ST(0) = sv_newmortal();
+ if( rpcb_gettime( host, &timep ) )
+ sv_setnv( ST(0), (double)timep );
+ }
+
+ Netconfig *
+ getnetconfigent(netid="udp")
+ char *netid
+
+ MODULE = RPC PACKAGE = NetconfigPtr PREFIX = rpcb_
+
+ void
+ rpcb_DESTROY(netconf)
+ Netconfig *netconf
+ CODE:
+ printf("NetconfigPtr::DESTROY\n");
+ free( netconf );
+
+File C<typemap>: Custom typemap for RPC.xs.
+
+ TYPEMAP
+ Netconfig * T_PTROBJ
+
+File C<RPC.pm>: Perl module for the RPC extension.
+
+ package RPC;
+
+ require Exporter;
+ require DynaLoader;
+ @ISA = qw(Exporter DynaLoader);
+ @EXPORT = qw(rpcb_gettime getnetconfigent);
+
+ bootstrap RPC;
+ 1;
+
+File C<rpctest.pl>: Perl test program for the RPC extension.
+
+ use RPC;
+
+ $netconf = getnetconfigent();
+ $a = rpcb_gettime();
+ print "time = $a\n";
+ print "netconf = $netconf\n";
+
+ $netconf = getnetconfigent("tcp");
+ $a = rpcb_gettime("poplar");
+ print "time = $a\n";
+ print "netconf = $netconf\n";
+
+
+=head1 AUTHOR
+
+Dean Roehrich F<E<lt>roehrich@cray.comE<gt>>
+Oct 12, 1995