<P>The PPCODE: keyword is an alternate form of the CODE: keyword and is used
to tell the <STRONG>xsubpp</STRONG> 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 should not be used
together within the same XSUB.</P>
<P>The actual difference between PPCODE: and CODE: sections is in the
initialization of <CODE>SP</CODE> macro (which stands for the <EM>current</EM> Perl
stack pointer), and in the handling of data on the stack when returning
from an XSUB. In CODE: sections SP preserves the value which was on
entry to the XSUB: SP is on the function pointer (which follows the
last parameter). In PPCODE: sections SP is moved backward to the
beginning of the parameter list, which allows <CODE>PUSH*()</CODE> macros
to place output values in the place Perl expects them to be when
the XSUB returns back to Perl.</P>
<P>The generated trailer for a CODE: section ensures that the number of return
values Perl will see is either 0 or 1 (depending on the <A HREF="../../lib/Pod/perlguts.html#item_void"><CODE>void</CODE></A>ness of the
return value of the C function, and heuristics mentioned in
<A HREF="#the retval variable">The RETVAL Variable</A>). The trailer generated for a PPCODE: section
is based on the number of return values and on the number of times
<CODE>SP</CODE> was updated by <CODE>[X]PUSH*()</CODE> macros.</P>
<P>Note that macros <CODE>ST(i)</CODE>, <CODE>XST_m*()</CODE> and <CODE>XSRETURN*()</CODE> work equally
well in CODE: sections and PPCODE: sections.</P>
<P>The following XSUB will call the C <CODE>rpcb_gettime()</CODE> function
and will return its two output values, timep and status, to
Perl as a single list.</P>
<PRE>
void
rpcb_gettime(host)
char *host
PREINIT:
time_t timep;
bool_t status;
PPCODE:
status = rpcb_gettime( host, &timep );
EXTEND(SP, 2);
PUSHs(sv_2mortal(newSViv(status)));
PUSHs(sv_2mortal(newSViv(timep)));</PRE>
<P>Notice that the programmer must supply the C code necessary
to have the real <CODE>rpcb_gettime()</CODE> function called and to have
the return values properly placed on the argument stack.</P>
<P>The <A HREF="../../lib/Pod/perlguts.html#item_void"><CODE>void</CODE></A> return type for this function tells the <STRONG>xsubpp</STRONG> 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.</P>
<P>The <CODE>EXTEND()</CODE> macro is used to make room on the argument
stack for 2 return values. The PPCODE: directive causes the
<STRONG>xsubpp</STRONG> compiler to create a stack pointer available as <CODE>SP</CODE>, and it
is this pointer which is being used in the <CODE>EXTEND()</CODE> macro.
The values are then pushed onto the stack with the <CODE>PUSHs()</CODE>
macro.</P>
<P>Now the <CODE>rpcb_gettime()</CODE> function can be used from Perl with
<P>The <CODE>&</CODE> unary operator in the INPUT: section is used to tell <STRONG>xsubpp</STRONG>
that it should convert a Perl value to/from C using the C type to the left
of <CODE>&</CODE>, but provide a pointer to this value when the C function is called.</P>
<P>This is useful to avoid a CODE: block for a C function which takes a parameter
by reference. Typically, the parameter should be not a pointer type (an
<A HREF="../../lib/Pod/perlfunc.html#item_int"><CODE>int</CODE></A> or <CODE>long</CODE> but not a <CODE>int*</CODE> or <CODE>long*</CODE>).</P>
<P>The following XSUB will generate incorrect C code. The <STRONG>xsubpp</STRONG> compiler will
turn this into code which calls <CODE>rpcb_gettime()</CODE> with parameters <CODE>(char
*host, time_t timep)</CODE>, but the real <CODE>rpcb_gettime()</CODE> wants the <CODE>timep</CODE>
parameter to be of type <CODE>time_t*</CODE> rather than <CODE>time_t</CODE>.</P>
<PRE>
bool_t
rpcb_gettime(host,timep)
char *host
time_t timep
OUTPUT:
timep</PRE>
<P>That problem is corrected by using the <CODE>&</CODE> operator. The <STRONG>xsubpp</STRONG> compiler
will now turn this into code which calls <CODE>rpcb_gettime()</CODE> correctly with
parameters <CODE>(char *host, time_t *timep)</CODE>. It does this by carrying the
<CODE>&</CODE> through, so the function call looks like <CODE>rpcb_gettime(host, &timep)</CODE>.</P>
<PRE>
bool_t
rpcb_gettime(host,timep)
char *host
time_t &timep
OUTPUT:
timep</PRE>
<P>
<H2><A NAME="inserting comments and c preprocessor directives">Inserting Comments and C Preprocessor Directives</A></H2>
<P>C preprocessor directives are allowed within BOOT:, PREINIT: INIT:,
CODE:, PPCODE:, and CLEANUP: blocks, as well as outside the functions.
Comments are allowed anywhere after the MODULE keyword. The compiler
will pass the preprocessor directives through untouched and will remove
the commented lines.</P>
<P>Comments can be added to XSUBs by placing a <CODE>#</CODE> as the first
non-whitespace of a line. Care should be taken to avoid making the
comment look like a C preprocessor directive, lest it be interpreted as
such. The simplest way to prevent this is to put whitespace in front of
the <CODE>#</CODE>.</P>
<P>If you use preprocessor directives to choose one of two
versions of a function, use</P>
<PRE>
#if ... version1
#else /* ... version2 */
#endif</PRE>
<P>and not</P>
<PRE>
#if ... version1
#endif
#if ... version2
#endif</PRE>
<P>because otherwise <STRONG>xsubpp</STRONG> will believe that you made a duplicate
definition of the function. Also, put a blank line before the
#else/#endif so it will not be seen as part of the function body.</P>
<P>
<H2><A NAME="using xs with c++">Using XS With C++</A></H2>
<P>If an XSUB name contains <CODE>::</CODE>, it is considered to be a C++ method.
The generated Perl function will assume that
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 <CODE>new()</CODE> function and should
be blessed by Perl with the <CODE>sv_setref_pv()</CODE> macro. The
blessing of the object by Perl can be handled by a typemap. An example
typemap is shown at the end of this section.</P>
<P>If the return type of the XSUB includes <CODE>static</CODE>, the method is considered
to be a static method. 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-><CODE>method()</CODE> syntax.</P>
<P>The next examples will use the following C++ class.</P>
<PRE>
class color {
public:
color();
~color();
int blue();
void set_blue( int );</PRE>
<PRE>
private:
int c_blue;
};</PRE>
<P>The XSUBs for the <CODE>blue()</CODE> and <CODE>set_blue()</CODE> methods are defined with the class
name but the parameter for the object (THIS, or ``self'') is implicit and is
not listed.</P>
<PRE>
int
color::blue()</PRE>
<PRE>
void
color::set_blue( val )
int val</PRE>
<P>Both Perl functions will expect an object as the first parameter. In the
generated C++ code the object is called <CODE>THIS</CODE>, and the method call will
be performed on this object. So in the C++ code the <CODE>blue()</CODE> and <CODE>set_blue()</CODE>
methods will be called as this:</P>
<PRE>
RETVAL = THIS->blue();</PRE>
<PRE>
THIS->set_blue( val );</PRE>
<P>You could also write a single get/set method using an optional argument:</P>
<PRE>
int
color::blue( val = NO_INIT )
int val
PROTOTYPE $;$
CODE:
if (items > 1)
THIS->set_blue( val );
RETVAL = THIS->blue();
OUTPUT:
RETVAL</PRE>
<P>If the function's name is <STRONG>DESTROY</STRONG> then the C++ <A HREF="../../lib/Pod/perlfunc.html#item_delete"><CODE>delete</CODE></A> function will be
called and <CODE>THIS</CODE> will be given as its parameter. The generated C++ code for</P>
<PRE>
void
color::DESTROY()</PRE>
<P>will look like this:</P>
<PRE>
color *THIS = ...; // Initialized as in typemap</PRE>
<PRE>
delete THIS;</PRE>
<P>If the function's name is <STRONG>new</STRONG> then the C++ <CODE>new</CODE> function will be called
to create a dynamic C++ object. The XSUB will expect the class name, which
will be kept in a variable called <CODE>CLASS</CODE>, to be given as the first
argument.</P>
<PRE>
color *
color::new()</PRE>
<P>The generated C++ code will call <CODE>new</CODE>.</P>
<PRE>
RETVAL = new color();</PRE>
<P>The following is an example of a typemap that could be used for this C++
example.</P>
<PRE>
TYPEMAP
color * O_OBJECT</PRE>
<PRE>
OUTPUT
# The Perl object is blessed into 'CLASS', which should be a
# char* having the name of the package for the blessing.