diff options
author | Andy Dougherty <doughera@lafcol.lafayette.edu> | 1995-10-31 03:33:09 +0000 |
---|---|---|
committer | Andy Dougherty <doughera@lafcol.lafayette.edu> | 1995-10-31 03:33:09 +0000 |
commit | 8e07c86ebc651fe92eb7e3b25f801f57cfb8dd6f (patch) | |
tree | bd67a65038befe4bef8b330a688bf7d915cab92f /pod/perlxs.pod | |
parent | e50aee73b3d4c555c37e4b4a16694765fb16c887 (diff) | |
download | perl-8e07c86ebc651fe92eb7e3b25f801f57cfb8dd6f.tar.gz |
This is my patch patch.1n for perl5.001.perl-5.001n
To apply, change to your perl directory, run the command above, then
apply with
patch -p1 -N < thispatch.
This is a consolidation patch. It contains many of the most commonly
applied or agreed-to patches that have been circulating since
patch.1m.
It also changes the 'unofficial patchlevel' in perl.c.
There are some problems (see items marked with '***').
I will attempt to address those in a patch.1o in a few days.
This patch contains the following packages:
My Jumbo Configure patch vs. 1m, with subsequent patches 1, 2, and 3.
Mainly, this provides easier use of local libraries, documents
the installation process in a new INSTALL file, moves important
questions towards the beginning, and improves detection of
signal names (mostly for Linux).
xsubpp-1.922.
Patches from Larry:
eval "1" memory leak patch (as modified by GSAR to apply to 5.001m).
NETaa14551 Infinite loop in formats,
NETaa13729 scope.c patch (fixed problems on AIX and others)
NETaa14138 "substr() & s///" (pp_hot.c)
Patches from ftp.perl.com:
ftp://ftp.perl.com/pub/perl/src/patches/closure-bug.patch,
version of 20 Sep 1995
Includes fix for NETaa14347 (32k limit in regex), and other
fixes.
ftp://ftp.perl.com/pub/perl/src/patches/debugger.patch,
version of 27 Aug 1995
ftp://ftp.perl.com/pub/perl/src/patches/glob-undef.patch,
version of 4 Sep 1995
NETaa14421 $_ doesn't undef
ftp://ftp.perl.com/pub/perl/src/patches/op-segfault.patch,
version of 21 Aug 1995
ftp://ftp.perl.com/pub/perl/src/patches/warn-ref-hash-key.patch,
version of 5 Jun 1995
Tim Bunce's Jumbo DynaLoader patch for Perl5.001m, which is
NETaa14636 Jumbo DynaLoader patch for Perl5.001m, and
Additional patch for NETaa14636 Jumbo DynaLoader patch for Perl5.001m
version of 09 Oct 1995.
***This needs some additional parentheses.***
MakeMaker-5.00. Supercedes NETaa13540 (VMS MakeMaker patches).
(Updates minimod.PL as well.)
***This has a couple of minor problems.
pod2man is run even if it isn't available.
LD_RUN_PATH gets set to some mysterious values.***
NETaa14657 Paul Marquess Net::Ping patch. I've included
Net-Ping-1.00.
NETaa14661 Dean Roehrich DProf. Installed as ext/Devel/DProf.
Configure should pick this up automatically. (5 Apr 1995
version.)
NETaa13742 Jack Shirazi Socket in 5.001. I've also included
his socket.t test in t/lib/socket.t.
c2ph-1.7.
Dean's perlapi patches of Oct 12, 1995, which superceded those
of Oct 8, 1995. This is the one that did
mv perlapi.pid perlxs.pod.
NETaa14310 Tim Bunce A trivial patch for configpm (handy for shell scripts)
DB_File-1.0 patch from Paul Marquess (pmarquess@bfsec.bt.co.uk)
last modified 7th October 1995
version 1.0
Added or updated the following hints files:
hints/hpux.sh
hints/ncr_tower.sh
hints/netbsd.sh
hints/ultrix.sh
Patch and enjoy.
Andy Dougherty doughera@lafcol.lafayette.edu
Dept. of Physics
Lafayette College, Easton PA 18042
Diffstat (limited to 'pod/perlxs.pod')
-rw-r--r-- | pod/perlxs.pod | 986 |
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 |