The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

A typical marshaller skeleton will look like this:

 static void
 some_custom_marshaler (GClosure * closure,
                        GValue * return_value,
                        guint n_param_values,
                        const GValue * param_values,
                        gpointer invocation_hint,
                        gpointer marshal_data)
 {
         dGPERL_CLOSURE_MARSHAL_ARGS;

         GPERL_CLOSURE_MARSHAL_INIT (closure, marshal_data);

         PERL_UNUSED_VAR (return_value);
         PERL_UNUSED_VAR (n_param_values);
         PERL_UNUSED_VAR (invocation_hint);

         ENTER;
         SAVETMPS;

         PUSHMARK (SP);

         GPERL_CLOSURE_MARSHAL_PUSH_INSTANCE (param_values);

         /*
          * push more parameters onto the perl stack... the ones
          * in which we are interested are param_values[1] through
          * param_values[n_param_values-1], because the 0th one
          * has been handled for us.
          */

         GPERL_CLOSURE_MARSHAL_PUSH_DATA;

         PUTBACK;

         /* this example invokes the callback in array context.
          * other options are G_DISCARD and G_SCALAR.  see C<call_sv>
          * in L<perlcall>. */
         GPERL_CLOSURE_MARSHAL_CALL (G_ARRAY);

         /*
          * get return values, if needed, and clean up.
          * "count" will contain the number of values returned on the
          * stack.
          */

         FREETMPS;
         LEAVE;
 }
dGPERL_CLOSURE_MARSHAL_ARGS

Declare several stack variables that the various GPERL_CLOSURE_MARSHAL macros will need. Declares SV ** sp for you. This must go near the top of your C function, before any code statements.

GPERL_CLOSURE_MARSHAL_INIT (closure, marshal_data)

This must be called as the first non-declaration statement in the marshaller function. In a threaded/threadable Perl, this ensures that all Perl API calls within the function happen in the same Perl interpreter that created the callback; if this is not first, strange things will happen. This statement also initalizes pc (the perl closure object) on the stack.

GPERL_CLOSURE_MARSHAL_PUSH_INSTANCE(param_values)

This pushes the callback's instance (first parameter) onto the Perl argument stack, with XPUSHs. Handles the case of swapped instance and data. param_values is the array of GValues passed into your marshaller. Note that the instance comes from param_values[0], so you needn't worry about that one when putting the rest of the parameters on the arg stack.

This assumes that n_param_values > 1.

GPERL_CLOSURE_MARSHAL_PUSH_DATA

Push the callback's user data onto the Perl arg stack, with XPUSHs. Handles the case of swapped instance and data. The user data is not included in param_values.

GPERL_CLOSURE_MARSHAL_CALL(flags)

Invoke the callback. You must ensure that all the arguments are already on the stack, and that you've called PUTBACK. This will invoke call_sv(), adding G_EVAL to the flags you supply, and store the return value in count on the stack (count is declared by dGPERL_CLOSURE_MARSHAL_ARGS). It then refreshes the stack pointer. If an exception occurred, the function returns after running exception handlers.

You'll be interested in the following values for flags:

 G_DISCARD
     this is effectively "void return", as it discards whatever the
     callback put on the return stack.
 G_SCALAR
     invoke the callback in scalar context.  you are pretty much
     guaranteed that one item will be on the stack, even if it is
     undef.
 G_ARRAY
     invoke the callback in array context.  C<count> (declared by
     C<dGPERL_CLOSURE_MARSHAL_ARGS>) will contain the number of
     items on the return stack.

As the callback is always run with G_EVAL, call_sv() will clobber ERRSV ($@); since closures are typically part of a mechanism that is transparent to the layer of Perl code that calls them, we save and restore ERRSV. Thus, code like

  eval { something that fails }
  $button->clicked;
  # $@ still has value from eval above

works as expected.

See call_sv in perlcall for more information.

dGPERL_CALLBACK_MARSHAL_SP

Declare the stack pointer such that it can be properly initialized by GPERL_CALLBACK_MARSHAL_INIT. Do not just use dSP. This should always come last in a list of declarations as its expansion might contain statements under certain conditions.

GPERL_CALLBACK_MARSHAL_INIT(callback)

Initialize the callback stuff. This must happen before any other Perl API statements in the callback marshaller. In a threaded Perl, this ensures that the proper interpreter context is used; if this isn't first, you'll mix and match two contexts and bad things will happen.

1 POD Error

The following errors were encountered while parsing the POD:

Around line 70:

'=item' outside of any '=over'

=over without closing =back