@@ -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