This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
[patch] more about embed.fnc in perlguts
[perl5.git] / pod / perlxstut.pod
index a697ecb..d1edf61 100644 (file)
@@ -210,7 +210,7 @@ that looks like this:
 
        Mytest::hello();
 
-Now we make the script executable (C<chmod -x hello>), run the script
+Now we make the script executable (C<chmod +x hello>), run the script
 and we should see the following output:
 
        % ./hello
@@ -233,9 +233,9 @@ Add the following to the end of Mytest.xs:
            OUTPUT:
                RETVAL
 
-There does not need to be white space at the start of the "C<int input>"
+There does not need to be whitespace at the start of the "C<int input>"
 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
+the end of that line is also optional.  Any amount and kind of whitespace
 may be placed between the "C<int>" and "C<input>".
 
 Now re-run make to rebuild our new shared library.
@@ -413,7 +413,7 @@ of round is of type "void".
 
 You specify the parameters that will be passed into the XSUB on the line(s)
 after you declare the function's return value and name.  Each input parameter
-line starts with optional white space, and may have an optional terminating
+line starts with optional whitespace, and may have an optional terminating
 semicolon.
 
 The list of output parameters occurs at the very end of the function, just
@@ -520,7 +520,7 @@ And finally create a file Makefile.PL that looks like this:
        WriteMakefile(
            NAME   => 'Mytest2::mylib',
            SKIP   => [qw(all static static_lib dynamic dynamic_lib)],
-           clean  => {'FILES' => 'libmylib$(LIBEEXT)'},
+           clean  => {'FILES' => 'libmylib$(LIB_EXT)'},
        );
 
 
@@ -692,7 +692,7 @@ makes these functions visible from Perl interpreter.
 
 Pay a special attention to the function C<constant>.  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
+function, then another time in the second part, when an XSUB interface to
 this static C function is defined.
 
 This is quite typical for .xs files: usually the .xs file provides
@@ -1229,20 +1229,45 @@ The real work is done in the standard typemap.
 B<But> you loose all the fine stuff done by the perlio layers. This
 calls the stdio function C<fputs()>, which knows nothing about them.
 
+The standard typemap offers three variants of PerlIO *:
+C<InputStream> (T_IN), C<InOutStream> (T_INOUT) and C<OutputStream>
+(T_OUT). A bare C<PerlIO *> is considered a T_INOUT. If it matters
+in your code (see below for why it might) #define or typedef
+one of the specific names and use that as the argument or result
+type in your XS file.
+
+The standard typemap does not contain PerlIO * before perl 5.7,
+but it has the three stream variants. Using a PerlIO * directly
+is not backwards compatible unless you provide your own typemap.
+
+For streams coming I<from> perl the main difference is that
+C<OutputStream> will get the output PerlIO * - which may make
+a difference on a socket. Like in our example...
+
+For streams being handed I<to> perl a new file handle is created
+(i.e. a reference to a new glob) and associated with the PerlIO *
+provided. If the read/write state of the PerlIO * is not correct then you
+may get errors or warnings from when the file handle is used.
+So if you opened the PerlIO * as "w" it should really be an
+C<OutputStream> if open as "r" it should be an C<InputStream>.
+
 Now, suppose you want to use perlio layers in your XS. We'll use the
 perlio C<PerlIO_puts()> function as an example.
 
-For PerlIO *'s, we need a typemap because the standard typemap does
-not provide C<PerlIO *>:
+In the C part of the XS file (above the first MODULE line) you
+have
+
+       #define OutputStream    PerlIO *
+    or
+       typedef PerlIO *        OutputStream;
 
-       PerlIO *                T_INOUT
 
 And this is the XS code:
 
        int
        perlioputs(s, stream)
                char *          s
-               PerlIO *        stream
+               OutputStream    stream
        CODE:
                RETVAL = PerlIO_puts(stream, s);
        OUTPUT:
@@ -1252,13 +1277,13 @@ We have to use a C<CODE> section because C<PerlIO_puts()> has the arguments
 reversed compared to C<fputs()>, and we want to keep the arguments the same.
 
 Wanting to explore this thoroughly, we want to use the stdio C<fputs()>
-on an explicit PerlIO *. This means we have to ask the perlio system
-for a stdio C<FILE *>:
+on a PerlIO *. This means we have to ask the perlio system for a stdio
+C<FILE *>:
 
        int
        perliofputs(s, stream)
                char *          s
-               PerlIO *        stream
+               OutputStream    stream
        PREINIT:
                FILE *fp = PerlIO_findFILE(stream);
        CODE:
@@ -1281,10 +1306,6 @@ generated by C<PerlIO_exportFILE()>.
 This applies to the perlio system only. For versions before 5.7,
 C<PerlIO_exportFILE()> is equivalent to C<PerlIO_findFILE()>.
 
-
-
-Getting fd's from filehandles
-
 =head2 Troubleshooting these Examples
 
 As mentioned at the top of this document, if you are having problems with
@@ -1335,7 +1356,8 @@ Jeff Okamoto <F<okamoto@corp.hp.com>>
 Reviewed and assisted by Dean Roehrich, Ilya Zakharevich, Andreas Koenig,
 and Tim Bunce.
 
-PerlIO material contributed by Lupe Christoph.
+PerlIO material contributed by Lupe Christoph, with some clarification
+by Nick Ing-Simmons.
 
 =head2 Last Changed