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
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.
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
WriteMakefile(
NAME => 'Mytest2::mylib',
SKIP => [qw(all static static_lib dynamic dynamic_lib)],
- clean => {'FILES' => 'libmylib$(LIBEEXT)'},
+ clean => {'FILES' => 'libmylib$(LIB_EXT)'},
);
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
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.
-For PerlIO *'s, there considered to be three kinds in the
-standard typemap 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 type in your XS file.
+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.
+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 *
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:
OUTPUT:
RETVAL
-(We also using bare PerlIO * as the type - so we get the I<input>
-PerlIO * of a socket - if this is undesirable use typedef or #define
-as above.)
-
Note: C<PerlIO_findFILE()> will search the layers for a stdio
layer. If it can't find one, it will call C<PerlIO_exportFILE()> to
generate a new stdio C<FILE>. Please only call C<PerlIO_exportFILE()> if