home *** CD-ROM | disk | FTP | other *** search
Text File | 2000-03-23 | 52.8 KB | 1,045 lines |
- <HTML>
- <HEAD>
- <TITLE>perlXStut - Tutorial for writing XSUBs</TITLE>
- <LINK REL="stylesheet" HREF="../../Active.css" TYPE="text/css">
- <LINK REV="made" HREF="mailto:">
- </HEAD>
-
- <BODY>
- <TABLE BORDER=0 CELLPADDING=0 CELLSPACING=0 WIDTH=100%>
- <TR><TD CLASS=block VALIGN=MIDDLE WIDTH=100% BGCOLOR="#cccccc">
- <STRONG><P CLASS=block> perlXStut - Tutorial for writing XSUBs</P></STRONG>
- </TD></TR>
- </TABLE>
-
- <A NAME="__index__"></A>
- <!-- INDEX BEGIN -->
-
- <UL>
-
- <LI><A HREF="#name">NAME</A></LI>
- <LI><A HREF="#description">DESCRIPTION</A></LI>
- <LI><A HREF="#special notes">SPECIAL NOTES</A></LI>
- <UL>
-
- <LI><A HREF="#make">make</A></LI>
- <LI><A HREF="#version caveat">Version caveat</A></LI>
- <LI><A HREF="#dynamic loading versus static loading">Dynamic Loading versus Static Loading</A></LI>
- </UL>
-
- <LI><A HREF="#tutorial">TUTORIAL</A></LI>
- <UL>
-
- <LI><A HREF="#example 1">EXAMPLE 1</A></LI>
- <LI><A HREF="#example 2">EXAMPLE 2</A></LI>
- <LI><A HREF="#what has gone on">What has gone on?</A></LI>
- <LI><A HREF="#writing good test scripts">Writing good test scripts</A></LI>
- <LI><A HREF="#example 3">EXAMPLE 3</A></LI>
- <LI><A HREF="#what's new here">What's new here?</A></LI>
- <LI><A HREF="#input and output parameters">Input and Output Parameters</A></LI>
- <LI><A HREF="#the xsubpp program">The XSUBPP Program</A></LI>
- <LI><A HREF="#the typemap file">The TYPEMAP file</A></LI>
- <LI><A HREF="#warning about output arguments">Warning about Output Arguments</A></LI>
- <LI><A HREF="#example 4">EXAMPLE 4</A></LI>
- <LI><A HREF="#what has happened here">What has happened here?</A></LI>
- <LI><A HREF="#anatomy of .xs file">Anatomy of .xs file</A></LI>
- <LI><A HREF="#getting the fat out of xsubs">Getting the fat out of XSUBs</A></LI>
- <LI><A HREF="#more about xsub arguments">More about XSUB arguments</A></LI>
- <LI><A HREF="#the argument stack">The Argument Stack</A></LI>
- <LI><A HREF="#extending your extension">Extending your Extension</A></LI>
- <LI><A HREF="#documenting your extension">Documenting your Extension</A></LI>
- <LI><A HREF="#installing your extension">Installing your Extension</A></LI>
- <LI><A HREF="#example 5">EXAMPLE 5</A></LI>
- <LI><A HREF="#new things in this example">New Things in this Example</A></LI>
- <LI><A HREF="#example 6 (coming soon)">EXAMPLE 6 (Coming Soon)</A></LI>
- <LI><A HREF="#example 7 (coming soon)">EXAMPLE 7 (Coming Soon)</A></LI>
- <LI><A HREF="#example 8 (coming soon)">EXAMPLE 8 (Coming Soon)</A></LI>
- <LI><A HREF="#example 9 (coming soon)">EXAMPLE 9 (Coming Soon)</A></LI>
- <LI><A HREF="#troubleshooting these examples">Troubleshooting these Examples</A></LI>
- </UL>
-
- <LI><A HREF="#see also">See also</A></LI>
- <LI><A HREF="#author">Author</A></LI>
- <UL>
-
- <LI><A HREF="#last changed">Last Changed</A></LI>
- </UL>
-
- </UL>
- <!-- INDEX END -->
-
- <HR>
- <P>
- <H1><A NAME="name">NAME</A></H1>
- <P>perlXStut - Tutorial for writing XSUBs</P>
- <P>
- <HR>
- <H1><A NAME="description">DESCRIPTION</A></H1>
- <P>This tutorial will educate the reader on the steps involved in creating
- a Perl extension. The reader is assumed to have access to <A HREF="../../lib/Pod/perlguts.html">the perlguts manpage</A> and
- <A HREF="../../lib/Pod/perlxs.html">the perlxs manpage</A>.</P>
- <P>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.</P>
- <P>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.</P>
- <P>
- <HR>
- <H1><A NAME="special notes">SPECIAL NOTES</A></H1>
- <P>
- <H2><A NAME="make">make</A></H2>
- <P>This tutorial assumes that the make program that Perl is configured to
- use is called <CODE>make</CODE>. Instead of running ``make'' in the examples that
- follow, you may have to substitute whatever make program Perl has been
- configured to use. Running <STRONG>perl -V:make</STRONG> should tell you what it is.</P>
- <P>
- <H2><A NAME="version caveat">Version caveat</A></H2>
- <P>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.</P>
- <P>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.</P>
- <P>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 <EM>README</EM> file, but nowadays
- installation of extensions may be performed automatically, guided by <EM>CPAN.pm</EM>
- module or other tools.</P>
- <P>In MakeMaker-based installations, <EM>Makefile.PL</EM> provides the earliest
- opportunity to perform version checks. One can put something like this
- in <EM>Makefile.PL</EM> for this purpose:</P>
- <PRE>
- eval { require 5.007 }
- or die <<EOD;
- ############
- ### This module uses frobnication framework which is not available before
- ### version 5.007 of Perl. Upgrade your Perl before installing Kara::Mba.
- ############
- EOD</PRE>
- <P>
- <H2><A NAME="dynamic loading versus static loading">Dynamic Loading versus Static Loading</A></H2>
- <P>It is commonly thought that if a system does not have the capability to
- dynamically load a library, you cannot build XSUBs. This is incorrect.
- You <EM>can</EM> 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.</P>
- <P>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.</P>
- <P>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 ``<CODE>make</CODE>'' with no arguments is executed, run the command
- ``<CODE>make perl</CODE>'' instead.</P>
- <P>If you have generated such a statically-linked executable by choice, then
- instead of saying ``<CODE>make test</CODE>'', you should say ``<CODE>make test_static</CODE>''.
- On systems that cannot build dynamically-loadable libraries at all, simply
- saying ``<CODE>make test</CODE>'' is sufficient.</P>
- <P>
- <HR>
- <H1><A NAME="tutorial">TUTORIAL</A></H1>
- <P>Now let's go on with the show!</P>
- <P>
- <H2><A NAME="example 1">EXAMPLE 1</A></H2>
- <P>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.</P>
- <P>Run ``<CODE>h2xs -A -n Mytest</CODE>''. This creates a directory named Mytest,
- possibly under ext/ if that directory exists in the current working
- directory. Several files will be created in the Mytest dir, including
- MANIFEST, Makefile.PL, Mytest.pm, Mytest.xs, test.pl, and Changes.</P>
- <P>The MANIFEST file contains the names of all the files just created in the
- Mytest directory.</P>
- <P>The file Makefile.PL should look something like this:</P>
- <PRE>
- 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'
- );</PRE>
- <P>The file Mytest.pm should start with something like this:</P>
- <PRE>
- package Mytest;</PRE>
- <PRE>
- use strict;
- use warnings;</PRE>
- <PRE>
- require Exporter;
- require DynaLoader;</PRE>
- <PRE>
- our @ISA = qw(Exporter DynaLoader);
- # Items to export into callers namespace by default. Note: do not export
- # names by default without a very good reason. Use EXPORT_OK instead.
- # Do not simply export all your public functions/methods/constants.
- our @EXPORT = qw(</PRE>
- <PRE>
- );
- our $VERSION = '0.01';</PRE>
- <PRE>
- bootstrap Mytest $VERSION;</PRE>
- <PRE>
- # Preloaded methods go here.</PRE>
- <PRE>
- # Autoload methods go after __END__, and are processed by the autosplit program.</PRE>
- <PRE>
- 1;
- __END__
- # Below is the stub of documentation for your module. You better edit it!</PRE>
- <P>The rest of the .pm file contains sample code for providing documentation for
- the extension.</P>
- <P>Finally, the Mytest.xs file should look something like this:</P>
- <PRE>
- #include "EXTERN.h"
- #include "perl.h"
- #include "XSUB.h"</PRE>
- <PRE>
- MODULE = Mytest PACKAGE = Mytest</PRE>
- <P>Let's edit the .xs file by adding this to the end of the file:</P>
- <PRE>
- void
- hello()
- CODE:
- printf("Hello, world!\n");</PRE>
- <P>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.</P>
- <P>Now we'll run ``<CODE>perl Makefile.PL</CODE>''. This will create a real Makefile,
- which make needs. Its output looks something like:</P>
- <PRE>
- % perl Makefile.PL
- Checking if your kit is complete...
- Looks good
- Writing Makefile for Mytest
- %</PRE>
- <P>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):</P>
- <PRE>
- % make
- umask 0 && cp Mytest.pm ./blib/Mytest.pm
- perl xsubpp -typemap typemap Mytest.xs >Mytest.tc && mv Mytest.tc Mytest.c
- Please specify prototyping behavior for Mytest.xs (see <A HREF="../../lib/Pod/perlxs.html">perlxs</A> manual)
- cc -c Mytest.c
- Running Mkbootstrap for Mytest ()
- chmod 644 Mytest.bs
- LD_RUN_PATH="" ld -o ./blib/PA-RISC1.1/auto/Mytest/Mytest.sl -b Mytest.o
- chmod 755 ./blib/PA-RISC1.1/auto/Mytest/Mytest.sl
- cp Mytest.bs ./blib/PA-RISC1.1/auto/Mytest/Mytest.bs
- chmod 644 ./blib/PA-RISC1.1/auto/Mytest/Mytest.bs
- Manifying ./blib/man3/Mytest.3
- %</PRE>
- <P>You can safely ignore the line about ``prototyping behavior''.</P>
- <P>If you are on a Win32 system, and the build process fails with linker
- errors for functions in the C library, check if your Perl is configured
- to use PerlCRT (running <STRONG>perl -V:libc</STRONG> should show you if this is the
- case). If Perl is configured to use PerlCRT, you have to make sure
- PerlCRT.lib is copied to the same location that msvcrt.lib lives in,
- so that the compiler can find it on its own. msvcrt.lib is usually
- found in the Visual C compiler's lib directory (e.g. C:/DevStudio/VC/lib).</P>
- <P>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:</P>
- <PRE>
- #! /opt/perl5/bin/perl</PRE>
- <PRE>
- use ExtUtils::testlib;</PRE>
- <PRE>
- use Mytest;</PRE>
- <PRE>
- Mytest::hello();</PRE>
- <P>Now we make the script executable (<CODE>chmod -x hello</CODE>), run the script
- and we should see the following output:</P>
- <PRE>
- % ./hello
- Hello, world!
- %</PRE>
- <P>
- <H2><A NAME="example 2">EXAMPLE 2</A></H2>
- <P>Now let's add to our extension a subroutine that will take a single numeric
- argument as input and return 0 if the number is even or 1 if the number
- is odd.</P>
- <P>Add the following to the end of Mytest.xs:</P>
- <PRE>
- int
- is_even(input)
- int input
- CODE:
- RETVAL = (input % 2 == 0);
- OUTPUT:
- RETVAL</PRE>
- <P>There does not need to be white space at the start of the ``<CODE>int input</CODE>''
- 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 white space
- may be placed between the ``<A HREF="../../lib/Pod/perlfunc.html#item_int"><CODE>int</CODE></A>'' and ``<CODE>input</CODE>''.</P>
- <P>Now re-run make to rebuild our new shared library.</P>
- <P>Now perform the same steps as before, generating a Makefile from the
- Makefile.PL file, and running make.</P>
- <P>In order to test that our extension works, we now need to look at the
- file test.pl. 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. Change the print
- statement in the BEGIN block to print ``1..4'', and add the following code
- to the end of the file:</P>
- <PRE>
- print &Mytest::is_even(0) == 1 ? "ok 2" : "not ok 2", "\n";
- print &Mytest::is_even(1) == 0 ? "ok 3" : "not ok 3", "\n";
- print &Mytest::is_even(2) == 1 ? "ok 4" : "not ok 4", "\n";</PRE>
- <P>We will be calling the test script through the command ``<CODE>make test</CODE>''. You
- should see output that looks something like this:</P>
- <PRE>
- % make test
- PERL_DL_NONLAZY=1 /opt/perl5.004/bin/perl (lots of -I arguments) test.pl
- 1..4
- ok 1
- ok 2
- ok 3
- ok 4
- %</PRE>
- <P>
- <H2><A NAME="what has gone on">What has gone on?</A></H2>
- <P>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.</P>
- <P>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.</P>
- <P>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.</P>
- <P>Generating the Makefile and running <CODE>make</CODE> 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.</P>
- <P>Invoking the test script via ``<CODE>make test</CODE>'' did something very important.
- It invoked perl with all those <CODE>-I</CODE> arguments so that it could find the
- various files that are part of the extension. It is <EM>very</EM> important that
- while you are still testing extensions that you use ``<CODE>make test</CODE>''. If you
- try to run the test script all by itself, you will get a fatal error.
- Another reason it is important to use ``<CODE>make test</CODE>'' to run your test
- script is that if you are testing an upgrade to an already-existing version,
- using ``<CODE>make test</CODE>'' insures that you will test your new extension, not the
- already-existing version.</P>
- <P>When Perl sees a <CODE>use extension;</CODE>, it searches for a file with the same name
- as the <A HREF="../../lib/Pod/perlfunc.html#item_use"><CODE>use</CODE></A>'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
- <CODE>@INC</CODE> array.</P>
- <P>In our case, Mytest.pm tells perl that it will need the Exporter and Dynamic
- Loader extensions. It then sets the <CODE>@ISA</CODE> and <CODE>@EXPORT</CODE> arrays and the
- <CODE>$VERSION</CODE> 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.</P>
- <P>The two arrays <CODE>@ISA</CODE> and <CODE>@EXPORT</CODE> are very important. The <CODE>@ISA</CODE>
- 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.</P>
- <P>The <CODE>@EXPORT</CODE> 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 <EM>not</EM>
- export method or variable names <EM>by default</EM> without a good reason.</P>
- <P>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 <CODE>@EXPORT_OK</CODE>. This array
- does not automatically place its subroutine and variable names into the
- namespace unless the user specifically requests that this be done.</P>
- <P>See <A HREF="../../lib/Pod/perlmod.html">the perlmod manpage</A> for more information.</P>
- <P>The <CODE>$VERSION</CODE> 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.</P>
- <P>
- <H2><A NAME="writing good test scripts">Writing good test scripts</A></H2>
- <P>The importance of writing good test scripts cannot be overemphasized. 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.</P>
- <P>By running ``<CODE>make test</CODE>'', you ensure that your test.pl script runs and uses
- the correct version of your extension. If you have many test cases, you
- might want to copy Perl's test style. Create a directory named ``t'' in the
- extension's directory and append the suffix ``.t'' to the names of your test
- files. When you run ``<CODE>make test</CODE>'', all of these test files will be executed.</P>
- <P>
- <H2><A NAME="example 3">EXAMPLE 3</A></H2>
- <P>Our third extension will take one argument as its input, round off that
- value, and set the <EM>argument</EM> to the rounded value.</P>
- <P>Add the following to the end of Mytest.xs:</P>
- <PRE>
- 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</PRE>
- <P>Edit the Makefile.PL file so that the corresponding line looks like this:</P>
- <PRE>
- 'LIBS' => ['-lm'], # e.g., '-lm'</PRE>
- <P>Generate the Makefile and run make. Change the BEGIN block to print
- ``1..9'' and add the following to test.pl:</P>
- <PRE>
- $i = -1.5; &Mytest::round($i); print $i == -2.0 ? "ok 5" : "not ok 5", "\n";
- $i = -1.1; &Mytest::round($i); print $i == -1.0 ? "ok 6" : "not ok 6", "\n";
- $i = 0.0; &Mytest::round($i); print $i == 0.0 ? "ok 7" : "not ok 7", "\n";
- $i = 0.5; &Mytest::round($i); print $i == 1.0 ? "ok 8" : "not ok 8", "\n";
- $i = 1.2; &Mytest::round($i); print $i == 1.0 ? "ok 9" : "not ok 9", "\n";</PRE>
- <P>Running ``<CODE>make test</CODE>'' should now print out that all nine tests are okay.</P>
- <P>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 test.pl:</P>
- <PRE>
- &Mytest::round(3);</PRE>
- <P>Run ``<CODE>make test</CODE>'' and notice that Perl dies with a fatal error. Perl won't
- let you change the value of constants!</P>
- <P>
- <H2><A NAME="what's new here">What's new here?</A></H2>
- <UL>
- <LI>
- 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.
- <P></P>
- <LI>
- 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''.
- <P></P></UL>
- <P>
- <H2><A NAME="input and output parameters">Input and Output Parameters</A></H2>
- <P>You specify the parameters that will be passed into the XSUB on the <CODE>line(s)</CODE>
- after you declare the function's return value and name. Each input parameter
- line starts with optional white space, and may have an optional terminating
- semicolon.</P>
- <P>The list of output parameters occurs at the very end of the function, just
- before 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.</P>
- <P>
- <H2><A NAME="the xsubpp program">The XSUBPP Program</A></H2>
- <P>The <STRONG>xsubpp</STRONG> 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.</P>
- <P>
- <H2><A NAME="the typemap file">The TYPEMAP file</A></H2>
- <P>The <STRONG>xsubpp</STRONG> 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). This file is split into
- three parts.</P>
- <P>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 <STRONG>xsubpp</STRONG> uses to handle input parameters. The third section contains
- C code which <STRONG>xsubpp</STRONG> uses to handle output parameters.</P>
- <P>Let's take a look at a portion of the .c file created for our extension.
- The file name is Mytest.c:</P>
- <PRE>
- XS(XS_Mytest_round)
- {
- dXSARGS;
- if (items != 1)
- croak("Usage: Mytest::round(arg)");
- {
- 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 */
- }
- XSRETURN(1);
- }</PRE>
- <P>Notice the two lines commented with ``XXXXX''. If you check the first section
- of the typemap file, you'll see that doubles are of type T_DOUBLE. In the
- INPUT section, 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 <A HREF="../../lib/Pod/perlguts.html">the perlguts manpage</A>; we'll talk more later about what that ``ST(0)'' means in the
- section on the argument stack.</P>
- <P>
- <H2><A NAME="warning about output arguments">Warning about Output Arguments</A></H2>
- <P>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 accomodate calling pre-existing C
- routines, which often do modify their input parameters, this behavior is
- tolerated.</P>
- <P>
- <H2><A NAME="example 4">EXAMPLE 4</A></H2>
- <P>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.</P>
- <P>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.</P>
- <P>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.</P>
- <P>In the mylib directory, create a file mylib.h that looks like this:</P>
- <PRE>
- #define TESTVAL 4</PRE>
- <PRE>
- extern double foo(int, long, const char*);</PRE>
- <P>Also create a file mylib.c that looks like this:</P>
- <PRE>
- #include <stdlib.h>
- #include "./mylib.h"</PRE>
- <PRE>
- double
- foo(int a, long b, const char *c)
- {
- return (a + b + atof(c) + TESTVAL);
- }</PRE>
- <P>And finally create a file Makefile.PL that looks like this:</P>
- <PRE>
- use ExtUtils::MakeMaker;
- $Verbose = 1;
- WriteMakefile(
- NAME => 'Mytest2::mylib',
- SKIP => [qw(all static static_lib dynamic dynamic_lib)],
- clean => {'FILES' => 'libmylib$(LIBEEXT)'},
- );</PRE>
- <PRE>
- sub MY::top_targets {
- '
- all :: static</PRE>
- <PRE>
- pure_all :: static</PRE>
- <PRE>
- static :: libmylib$(LIB_EXT)</PRE>
- <PRE>
- libmylib$(LIB_EXT): $(O_FILES)
- $(AR) cr libmylib$(LIB_EXT) $(O_FILES)
- $(RANLIB) libmylib$(LIB_EXT)</PRE>
- <PRE>
- ';
- }</PRE>
- <P>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.</P>
- <P>We will now create the main top-level Mytest2 files. Change to the directory
- above Mytest2 and run the following command:</P>
- <PRE>
- % h2xs -O -n Mytest2 ./Mytest2/mylib/mylib.h</PRE>
- <P>This will print out a warning about overwriting Mytest2, but that's okay.
- Our files are stored in Mytest2/mylib, and will be untouched.</P>
- <P>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:</P>
- <PRE>
- 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)',
- );</PRE>
- <P>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''!</P>
- <PRE>
- sub MY::postamble {
- '
- $(MYEXTLIB): mylib/Makefile
- cd mylib && $(MAKE) $(PASSTHRU)
- ';
- }</PRE>
- <P>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:</P>
- <PRE>
- mylib/Makefile.PL
- mylib/mylib.c
- mylib/mylib.h</PRE>
- <P>To keep our namespace nice and unpolluted, edit the .pm file and change
- the variable <CODE>@EXPORT</CODE> to <CODE>@EXPORT_OK</CODE>. Finally, in the
- .xs file, edit the #include line to read:</P>
- <PRE>
- #include "mylib/mylib.h"</PRE>
- <P>And also add the following function definition to the end of the .xs file:</P>
- <PRE>
- double
- foo(a,b,c)
- int a
- long b
- const char * c
- OUTPUT:
- RETVAL</PRE>
- <P>Now we also need to create a typemap file because the default Perl doesn't
- currently support the const char * type. Create a file called typemap in
- the Mytest2 directory and place the following in it:</P>
- <PRE>
- const char * T_PV</PRE>
- <P>Now run perl on the top-level Makefile.PL. Notice that it also created a
- Makefile in the mylib directory. Run make and watch that it does cd into
- the mylib directory and run make in there as well.</P>
- <P>Now edit the test.pl script and change the BEGIN block to print ``1..4'',
- and add the following lines to the end of the script:</P>
- <PRE>
- print &Mytest2::foo(1, 2, "Hello, world!") == 7 ? "ok 2\n" : "not ok 2\n";
- print &Mytest2::foo(1, 2, "0.0") == 7 ? "ok 3\n" : "not ok 3\n";
- print abs(&Mytest2::foo(0, 0, "-3.4") - 0.6) <= 0.01 ? "ok 4\n" : "not ok 4\n";</PRE>
- <P>(When dealing with floating-point comparisons, it is best to not check for
- equality, but rather that the difference between the expected and actual
- result is below a certain amount (called epsilon) which is 0.01 in this case)</P>
- <P>Run ``<CODE>make test</CODE>'' and all should be well.</P>
- <P>
- <H2><A NAME="what has happened here">What has happened here?</A></H2>
- <P>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.</P>
- <UL>
- <LI>
- 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.
- <P></P>
- <LI>
- There's now some new C code that's been added to the .xs file. The purpose
- of the <CODE>constant</CODE> routine is to make the values that are #define'd in the
- header file accessible by the Perl script (by calling either <CODE>TESTVAL</CODE> or
- <CODE>&Mytest2::TESTVAL</CODE>). There's also some XS code to allow calls to the
- <CODE>constant</CODE> routine.
- <P></P>
- <LI>
- The .pm file originally exported the name <CODE>TESTVAL</CODE> in the <CODE>@EXPORT</CODE> 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 <CODE>@EXPORT</CODE> 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 <CODE>@EXPORT</CODE> array into the <CODE>@EXPORT_OK</CODE> array.
- <P></P>
- <LI>
- 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.
- <P></P>
- <LI>
- We've also told Perl about the library that we built in the mylib
- subdirectory. That required only the addition of the <CODE>MYEXTLIB</CODE> 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.
- <P></P></UL>
- <P>
- <H2><A NAME="anatomy of .xs file">Anatomy of .xs file</A></H2>
- <P>The .xs file of <A HREF="#example 4">EXAMPLE 4</A> contained some new elements. To understand
- the meaning of these elements, pay attention to the line which reads</P>
- <PRE>
- MODULE = Mytest2 PACKAGE = Mytest2</PRE>
- <P>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, it goes into the generated output C file as is.</P>
- <P>Anything after this line is the description of XSUB functions.
- These descriptions are translated by <STRONG>xsubpp</STRONG> into C code which
- implements these functions using Perl calling conventions, and which
- makes these functions visible from Perl interpreter.</P>
- <P>Pay a special attention to the function <CODE>constant</CODE>. This name appears
- twice in the generated .xs file: once in the first part, as a static C
- function, the another time in the second part, when an XSUB interface to
- this static C function is defined.</P>
- <P>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 <A HREF="#example 1">EXAMPLE 1</A>, <A HREF="#example 2">EXAMPLE 2</A>,
- and <A HREF="#example 3">EXAMPLE 3</A>, when all the work is done inside the ``Perl glue'', is
- somewhat of an exception rather than the rule.</P>
- <P>
- <H2><A NAME="getting the fat out of xsubs">Getting the fat out of XSUBs</A></H2>
- <P>In <A HREF="#example 4">EXAMPLE 4</A> the second part of .xs file contained the following
- description of an XSUB:</P>
- <PRE>
- double
- foo(a,b,c)
- int a
- long b
- const char * c
- OUTPUT:
- RETVAL</PRE>
- <P>Note that in contrast with <A HREF="#example 1">EXAMPLE 1</A>, <A HREF="#example 2">EXAMPLE 2</A> and <A HREF="#example 3">EXAMPLE 3</A>,
- this description does not contain the actual <EM>code</EM> for what is done
- 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:</P>
- <PRE>
- double
- foo(a,b,c)
- int a
- long b
- const char * c
- CODE:
- RETVAL = foo(a,b,c);
- OUTPUT:
- RETVAL</PRE>
- <P>However, these two XSUBs provide almost identical generated C code: <STRONG>xsubpp</STRONG>
- compiler is smart enough to figure out the <CODE>CODE:</CODE> section from the first
- two lines of the description of XSUB. What about <CODE>OUTPUT:</CODE> section? In
- fact, that is absolutely the same! The <CODE>OUTPUT:</CODE> section can be removed
- as well, <EM>as far as <CODE>CODE:</CODE> section or <CODE>PPCODE:</CODE> section</EM> is not
- specified: <STRONG>xsubpp</STRONG> 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:</P>
- <PRE>
- double
- foo(a,b,c)
- int a
- long b
- const char * c</PRE>
- <P>Can we do the same with an XSUB</P>
- <PRE>
- int
- is_even(input)
- int input
- CODE:
- RETVAL = (input % 2 == 0);
- OUTPUT:
- RETVAL</PRE>
- <P>of <A HREF="#example 2">EXAMPLE 2</A>? To do this, one needs to define a C function <CODE>int
- is_even(int input)</CODE>. As we saw in <A HREF="#anatomy of .xs file">Anatomy of .xs file</A>, a proper place
- for this definition is in the first part of .xs file. In fact a C function</P>
- <PRE>
- int
- is_even(int arg)
- {
- return (arg % 2 == 0);
- }</PRE>
- <P>is probably overkill for this. Something as simple as a <CODE>#define</CODE> will
- do too:</P>
- <PRE>
- #define is_even(arg) ((arg) % 2 == 0)</PRE>
- <P>After having this in the first part of .xs file, the ``Perl glue'' part becomes
- as simple as</P>
- <PRE>
- int
- is_even(input)
- int input</PRE>
- <P>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 <STRONG>xsubpp</STRONG> might have translated this to TCL glue or
- Python glue as well.)</P>
- <P>
- <H2><A NAME="more about xsub arguments">More about XSUB arguments</A></H2>
- <P>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
- <STRONG>xsubpp</STRONG> compiler.</P>
- <P>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.</P>
- <P>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</P>
- <PRE>
- int string_length(char *s);
- int upper_case_char(char *cp);</PRE>
- <P>may have completely different semantics: the first one may inspect an array
- of chars pointed by s, and the second one may immediately dereference <CODE>cp</CODE>
- and manipulate <CODE>*cp</CODE> only (using the return value as, say, a success
- indicator). From Perl one would use these functions in
- a completely different manner.</P>
- <P>One conveys this info to <STRONG>xsubpp</STRONG> by replacing <CODE>*</CODE> before the
- argument by <CODE>&</CODE>. <CODE>&</CODE> means that the argument should be passed to a library
- function by its address. The above two function may be XSUB-ified as</P>
- <PRE>
- int
- string_length(s)
- char * s</PRE>
- <PRE>
- int
- upper_case_char(cp)
- char &cp</PRE>
- <P>For example, consider:</P>
- <PRE>
- int
- foo(a,b)
- char &a
- char * b</PRE>
- <P>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 <EM>value</EM> of b would be passed into the function foo. The
- actual call to the function foo that <STRONG>xsubpp</STRONG> generates would look like this:</P>
- <PRE>
- foo(&a, b);</PRE>
- <P><STRONG>xsubpp</STRONG> will parse the following function argument lists identically:</P>
- <PRE>
- char &a
- char&a
- char & a</PRE>
- <P>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''.</P>
- <P>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.</P>
- <P>
- <H2><A NAME="the argument stack">The Argument Stack</A></H2>
- <P>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. <CODE>ST(0)</CODE> is thus the first argument on the stack and
- therefore the first argument passed to the XSUB, <CODE>ST(1)</CODE> is the second
- argument, and so on.</P>
- <P>When you list the arguments to the XSUB in the .xs file, that tells <STRONG>xsubpp</STRONG>
- 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.</P>
- <P>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., <CODE>ST(0)</CODE> 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 <CODE>round()</CODE> XSUB routine contains lines that look like this:</P>
- <PRE>
- double arg = (double)SvNV(ST(0));
- /* Round the contents of the variable arg */
- sv_setnv(ST(0), (double)arg);</PRE>
- <P>The arg variable is initially set by taking the value from ST(0), then is
- stored back into <CODE>ST(0)</CODE> at the end of the routine.</P>
- <P>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 <A HREF="../../lib/Pod/perlxs.html">the perlxs manpage</A> for details.</P>
- <P>XSUBs are also allowed to avoid automatic conversion of Perl function arguments
- to C function arguments. See <A HREF="../../lib/Pod/perlxs.html">the perlxs manpage</A> for details. Some people prefer
- manual conversion by inspecting <CODE>ST(i)</CODE> even in the cases when automatic
- conversion will do, arguing that this makes the logic of an XSUB call clearer.
- Compare with <A HREF="#getting the fat out of xsubs">Getting the fat out of XSUBs</A> for a similar tradeoff of
- a complete separation of ``Perl glue'' and ``workhorse'' parts of an XSUB.</P>
- <P>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
- <A HREF="#getting the fat out of xsubs">Getting the fat out of XSUBs</A>. This approach has the additional
- benefit of protecting the XSUB writer from future changes to the Perl API.</P>
- <P>
- <H2><A NAME="extending your extension">Extending your Extension</A></H2>
- <P>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 <A HREF="../../lib/AutoLoader.html">the AutoLoader manpage</A> for an alternate
- way to store and load your extra subroutines.</P>
- <P>
- <H2><A NAME="documenting your extension">Documenting your Extension</A></H2>
- <P>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 man page format,
- then placed in the blib directory. It will be copied to Perl's man
- page directory when the extension is installed.</P>
- <P>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.</P>
- <P>See <A HREF="../../lib/Pod/perlpod.html">the perlpod manpage</A> for more information about the pod format.</P>
- <P>
- <H2><A NAME="installing your extension">Installing your Extension</A></H2>
- <P>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.</P>
- <P>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.</P>
- <P>
- <H2><A NAME="example 5">EXAMPLE 5</A></H2>
- <P>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.</P>
- <P>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.</P>
- <P>Return to the Mytest directory and add the following code to the end of
- Mytest.xs:</P>
- <PRE>
- void
- statfs(path)
- char * path
- INIT:
- int i;
- struct statfs buf;</PRE>
- <PRE>
- 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)));
- XPUSHs(sv_2mortal(newSVnv(buf.f_fsid[0])));
- XPUSHs(sv_2mortal(newSVnv(buf.f_fsid[1])));
- } else {
- XPUSHs(sv_2mortal(newSVnv(errno)));
- }</PRE>
- <P>You'll also need to add the following code to the top of the .xs file, just
- after the include of ``XSUB.h'':</P>
- <PRE>
- #include <sys/vfs.h></PRE>
- <P>Also add the following code segment to test.pl while incrementing the ``1..9''
- string in the BEGIN block to ``1..11'':</P>
- <PRE>
- @a = &Mytest::statfs("/blech");
- print ((scalar(@a) == 1 && $a[0] == 2) ? "ok 10\n" : "not ok 10\n");
- @a = &Mytest::statfs("/");
- print scalar(@a) == 9 ? "ok 11\n" : "not ok 11\n";</PRE>
- <P>
- <H2><A NAME="new things in this example">New Things in this Example</A></H2>
- <P>This example added quite a few new concepts. We'll take them one at a time.</P>
- <UL>
- <LI>
- 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 <CODE>PPCODE:</CODE> section into braces, and
- put these declarations on top.)
- <P></P>
- <LI>
- 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 9-element array is returned. Since only one argument is passed into
- this function, we need room on the stack to hold the 9 values which may be
- returned.
- <P>We do this by using the PPCODE: directive, rather than the CODE: directive.
- This tells <STRONG>xsubpp</STRONG> that we will be managing the return values that will be
- put on the argument stack by ourselves.</P>
- <P></P>
- <LI>
- 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.)
- <P>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.</P>
- <P></P>
- <LI>
- 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.
- <P></P>
- <LI>
- If we were interested in performance, not in code compactness, in the success
- branch we would not use <CODE>XPUSHs</CODE> macros, but <CODE>PUSHs</CODE> macros, and would
- pre-extend the stack before pushing the return values:
- <PRE>
- EXTEND(SP, 9);</PRE>
- <P>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).</P>
- <P>Similarly, in the failure branch we could use <CODE>PUSHs</CODE> <EM>without</EM> extending
- the stack: the Perl function reference comes to an XSUB on the stack, thus
- the stack is <EM>always</EM> large enough to take one return value.</P>
- <P></P></UL>
- <P>
- <H2><A NAME="example 6 (coming soon)">EXAMPLE 6 (Coming Soon)</A></H2>
- <P>Passing in and returning references to arrays and/or hashes</P>
- <P>
- <H2><A NAME="example 7 (coming soon)">EXAMPLE 7 (Coming Soon)</A></H2>
- <P>XPUSH args AND set RETVAL AND assign return value to array</P>
- <P>
- <H2><A NAME="example 8 (coming soon)">EXAMPLE 8 (Coming Soon)</A></H2>
- <P>Setting $!</P>
- <P>
- <H2><A NAME="example 9 (coming soon)">EXAMPLE 9 (Coming Soon)</A></H2>
- <P>Getting fd's from filehandles</P>
- <P>
- <H2><A NAME="troubleshooting these examples">Troubleshooting these Examples</A></H2>
- <P>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.</P>
- <UL>
- <LI>
- 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:
- <PRE>
- use lib './blib';</PRE>
- <P></P>
- <LI>
- 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:
- <PRE>
- use lib './blib';</PRE>
- <P></P>
- <LI>
- In versions 5.000 and 5.001, instead of using the above line, you will need
- to use the following line:
- <PRE>
- BEGIN { unshift(@INC, "./blib") }</PRE>
- <P></P>
- <LI>
- This document assumes that the executable named ``perl'' is Perl version 5.
- Some systems may have installed Perl version 5 as ``perl5''.
- <P></P></UL>
- <P>
- <HR>
- <H1><A NAME="see also">See also</A></H1>
- <P>For more information, consult <A HREF="../../lib/Pod/perlguts.html">the perlguts manpage</A>, <A HREF="../../lib/Pod/perlxs.html">the perlxs manpage</A>, <A HREF="../../lib/Pod/perlmod.html">the perlmod manpage</A>,
- and <A HREF="../../lib/Pod/perlpod.html">the perlpod manpage</A>.</P>
- <P>
- <HR>
- <H1><A NAME="author">Author</A></H1>
- <P>Jeff Okamoto <<EM><A HREF="mailto:okamoto@corp.hp.com">okamoto@corp.hp.com</A></EM>></P>
- <P>Reviewed and assisted by Dean Roehrich, Ilya Zakharevich, Andreas Koenig,
- and Tim Bunce.</P>
- <P>
- <H2><A NAME="last changed">Last Changed</A></H2>
- <P>1999/11/30</P>
- <TABLE BORDER=0 CELLPADDING=0 CELLSPACING=0 WIDTH=100%>
- <TR><TD CLASS=block VALIGN=MIDDLE WIDTH=100% BGCOLOR="#cccccc">
- <STRONG><P CLASS=block> perlXStut - Tutorial for writing XSUBs</P></STRONG>
- </TD></TR>
- </TABLE>
-
- </BODY>
-
- </HTML>
-