Skip to content

Commit 9717f25

Browse files
committed
perlxs.pod: update IN_OUT etc section
1 parent 955ad90 commit 9717f25

File tree

1 file changed

+151
-68
lines changed

1 file changed

+151
-68
lines changed

dist/ExtUtils-ParseXS/lib/perlxs.pod

Lines changed: 151 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -2180,90 +2180,173 @@ override the missing argument. For example:
21802180
foo(int a, b, char *c)
21812181
C_ARGS: a, c
21822182

2183-
=head3 The IN/OUTLIST/IN_OUTLIST/OUT/IN_OUT Keywords
2184-
2185-
In the list of parameters for an XSUB, one can precede parameter names
2186-
by the C<IN>/C<OUTLIST>/C<IN_OUTLIST>/C<OUT>/C<IN_OUT> keywords.
2187-
C<IN> keyword is the default, the other keywords indicate how the Perl
2188-
interface should differ from the C interface.
2189-
2190-
Parameters preceded by C<OUTLIST>/C<IN_OUTLIST>/C<OUT>/C<IN_OUT>
2191-
keywords are considered to be used by the C subroutine I<via
2192-
pointers>. C<OUTLIST>/C<OUT> keywords indicate that the C subroutine
2193-
does not inspect the memory pointed by this parameter, but will write
2194-
through this pointer to provide additional return values.
2195-
2196-
Parameters preceded by C<OUTLIST> keyword do not appear in the usage
2197-
signature of the generated Perl function.
2198-
2199-
Parameters preceded by C<IN_OUTLIST>/C<IN_OUT>/C<OUT> I<do> appear as
2200-
parameters to the Perl function. With the exception of
2201-
C<OUT>-parameters, these parameters are converted to the corresponding
2202-
C type, then pointers to these data are given as arguments to the C
2203-
function. It is expected that the C function will write through these
2204-
pointers.
2205-
2206-
The return list of the generated Perl function consists of the C return value
2207-
from the function (unless the XSUB is of C<void> return type or
2208-
C<NO_OUTPUT> was used) followed by all the C<OUTLIST>
2209-
and C<IN_OUTLIST> parameters (in the order of appearance). On the
2210-
return from the XSUB the C<IN_OUT>/C<OUT> Perl parameter will be
2211-
modified to have the values written by the C function.
2212-
2213-
For example, an XSUB
2183+
=head3 Updating and returning parameter values: the IN_OUT etc keywords
22142184

2215-
void
2216-
day_month(OUTLIST day, IN unix_time, OUTLIST month)
2217-
int day
2218-
int unix_time
2219-
int month
2185+
int i
2186+
IN int i
2187+
IN_OUT int i
2188+
IN_OUTLIST int i
2189+
OUT int i
2190+
OUTLIST int i
22202191

2221-
should be used from Perl as
2192+
Normally a parameter declaration causes a C auto variable of the same name
2193+
to be declared and initialised to the value of the corresponding passed
2194+
argument. These modifiers can make parameters also update or return
2195+
values, and can also cause the initialisation to be skipped. They come at
2196+
the start of a parameter declaration.
22222197

2223-
my ($day, $month) = day_month(time);
2198+
These modifiers address the issue that, because a simple C function takes
2199+
a fixed number of I<read-only> parameters and returns a I<single> value,
2200+
the basic XSUB syntax has been designed to reflect that pattern.
22242201

2225-
The C signature of the corresponding function should be
2202+
The usual way to make a more complex C function API is to pass pointers to
2203+
variables, which the C function will use to set or update the variables.
2204+
For example, a couple of hypothetical C functions might be called as:
22262205

2227-
void day_month(int *day, int unix_time, int *month);
2206+
int time = ....; // an integer in the range 0..86399
2207+
int hour, min, sec;
2208+
parse_time(time, &hour, &min, &sec); // set hour, min, sec
2209+
increment_time(&hour, &min, &sec); // update hour, min, sec
22282210

2229-
The C<IN>/C<OUTLIST>/C<IN_OUTLIST>/C<IN_OUT>/C<OUT> keywords can be
2230-
mixed with ANSI-style declarations, as in
2211+
The XS C<IN_OUT> etc modifiers allow you to write XSUBs which can wrap
2212+
such functions with autocall, and in general update passed arguments or
2213+
return multiple values.
22312214

2232-
void
2233-
day_month(OUTLIST int day, int unix_time, OUTLIST int month)
2215+
The rules of these parameter modifiers are:
2216+
2217+
=over
2218+
2219+
=item *
2220+
2221+
All such parameters, regardless of the modifier, cause a C auto variable
2222+
of the same name to be declared.
2223+
2224+
=item *
2225+
2226+
In the absence of a modifier, it defaults to C<IN>.
2227+
2228+
=item *
2229+
2230+
The text of the modifier has up to two parts, separated by an underscore.
2231+
The input part comes first and can have the value C<''> or C<IN>, while
2232+
the output part can be one of C<''>, C<OUT>, or C<OUTLIST>.
2233+
2234+
=item *
2235+
2236+
An input part of C<IN> (the default) causes that variable to be
2237+
initialised to the value of the corresponding passed argument. Otherwise
2238+
the initialisation is skipped: in particular, this means that an autocall
2239+
function will be passed a pointer to an uninitialised value: the
2240+
assumption being that the library function will set, but not use, that
2241+
value.
2242+
2243+
=item *
2244+
2245+
An output part of C<''> (the default) means nothing is done to return the
2246+
value of the auto variable.
2247+
2248+
=item *
2249+
2250+
An output part of C<OUT> or C<OUTLIST> causes the value to be returned in
2251+
some fashion, and in addition, any autocall code will prefix such
2252+
variables with C<&> when calling the wrapped C library function.
22342253

2235-
(here the optional C<IN> keyword is omitted).
2254+
=item *
2255+
2256+
An output part of C<OUT> causes the corresponding passed argument to be
2257+
I<updated> with the value of the variable.
2258+
2259+
=item *
2260+
2261+
An output part of C<OUTLIST> causes the value of the variable to be
2262+
returned as an extra SV after the C<RETVAL> value, if any. They are
2263+
returned in the order they appear in the XSUB's parameter list.
2264+
2265+
=item *
2266+
2267+
For the specific case of the modifier being C<OUTLIST>, it is a
2268+
pseudo-parameter, and I<no argument is consumed>. It doesn't form part of
2269+
the signature of the XSUB, although it I<is> used for any autocall. So for
2270+
example:
2271+
2272+
int
2273+
foo(int a, OUTLIST int b, int c)
22362274

2237-
The C<IN_OUT> parameters are identical with parameters introduced with
2238-
L<The & Unary Operator> and put into the C<OUTPUT:> section (see
2239-
L<The OUTPUT: Keyword>). The C<IN_OUTLIST> parameters are very similar,
2240-
the only difference being that the value C function writes through the
2241-
pointer would not modify the Perl parameter, but is put in the output
2242-
list.
2275+
gets converted to roughly this C code:
22432276

2244-
The C<OUTLIST>/C<OUT> parameter differ from C<IN_OUTLIST>/C<IN_OUT>
2245-
parameters only by the initial value of the Perl parameter not
2246-
being read (and not being given to the C function - which gets some
2247-
garbage instead). For example, the same C function as above can be
2248-
interfaced with as
2277+
if (items != 2)
2278+
croak_xs_usage(cv, "a, c");
2279+
{
2280+
int RETVAL;
2281+
int a = (int)SvIV(ST(0));
2282+
int b;
2283+
int c = (int)SvIV(ST(1));
2284+
RETVAL = foo(a, &b, c);
2285+
}
2286+
... push the values of RETVAL and b onto the stack and return ...
22492287

2250-
void day_month(OUT int day, int unix_time, OUT int month);
2288+
=back
22512289

2252-
or
2290+
The approximate perl equivalents for these modifiers are given in the
2291+
examples below, where the perl code C<real_foo(\$i)> stands in for the C
2292+
autocall C<foo(&i)>.
2293+
2294+
2295+
int i sub foo {
2296+
IN int i my $i = $_[N];
2297+
real_foo($i);
2298+
}
2299+
2300+
IN_OUT int i sub foo {
2301+
my $i = $_[N];
2302+
real_foo(\$i);
2303+
$_[N] = $i;
2304+
}
2305+
2306+
IN_OUTLIST int i sub foo {
2307+
my $i = $_[N];
2308+
real_foo(\$i);
2309+
return ..., $i, ...;
2310+
}
2311+
2312+
OUT int i sub foo {
2313+
my $i;
2314+
real_foo(\$i);
2315+
$_[N] = $i;
2316+
2317+
OUTLIST int i sub foo {
2318+
my $i; # NB $_[N] is not consumed
2319+
real_foo(\$i);
2320+
return ..., $i, ...;
2321+
}
2322+
2323+
Together, they allow you to wrap C functions which use pointers to return
2324+
extra values; either preserving the C-ish API in perl (C<OUT>), or
2325+
providing a more Perl-like API (C<OUTLIST>). For example, wrapping the
2326+
C<parse_time()> function from the example above could be done using
2327+
C<OUT>:
22532328

22542329
void
2255-
day_month(day, unix_time, month)
2256-
int &day = NO_INIT
2257-
int unix_time
2258-
int &month = NO_INIT
2259-
OUTPUT:
2260-
day
2261-
month
2330+
parse_time(int time, \
2331+
OUT int hour, OUT int min, OUT int sec)
2332+
2333+
which could be called from perl as:
2334+
2335+
my ($hour, $min, $sec);
2336+
# set ($hour, $min, $sec) to (23,59,59):
2337+
parse_time(86399, $hour, $min, $sec);
2338+
2339+
Or by using C<OUTLIST>:
2340+
2341+
void
2342+
parse_time(int time, \
2343+
OUTLIST int hour, OUTLIST int min, OUTLIST int sec)
2344+
2345+
which could be called from perl as:
22622346

2263-
However, the generated Perl function is called in very C-ish style:
2347+
# set ($hour, $min, $sec) to (23,59,59):
2348+
my ($hour, $min, $sec) = parse_time(86399);
22642349

2265-
my ($day, $month);
2266-
day_month($day, time, $month);
22672350

22682351
=head3 Default Parameter Values
22692352

0 commit comments

Comments
 (0)