XS-Framework

 view release on metacpan or  search on metacpan

lib/XS/Framework/Manual/Typemap.pod  view on Meta::CPAN

It assumes that XS-adapter returns std::shared_ptr<MyClass> to Perl, i.e. object
I<ownership is shared> between C++ and Perl.

=head3 C++ typemap lifetime policy feature matrix

=begin comment

Feature	ObjectTypePtr	ObjectTypeForeignPtr	ObjectTypeRefcntPtr	ObjectTypeSharedPtr
transfers ownership	+	-	-	-
shares ownership    -	-	+	+
foreign ownership	-	+	-	-

=end comment

=begin text

+-------------------------+---------------+----------------------+---------------------+---------------------+
|         Feature         | ObjectTypePtr | ObjectTypeForeignPtr | ObjectTypeRefcntPtr | ObjectTypeSharedPtr |
+-------------------------+---------------+----------------------+---------------------+---------------------+
| transfers ownership     | +             | -                    | -                   | -                   |
| shares ownership        | -             | -                    | +                   | +                   |
| foreign ownership       | -             | +                    | -                   | -                   |
+-------------------------+---------------+----------------------+---------------------+---------------------+

=end text

=head3 C<out> behaviour

The C<out> method has optional C<const Sv& proto = {}> parameter, which instructs
how make the C++ pointer accessible in Perl.

=over 4

=item it might be empty

In that case SV* pointing to C<undef> is created, and it is blessed into C<package()>
returned by the TypemapObject.

This is automatically applied behaviour by ParseXS for the output parameters, i.e.
C<ClassXXX> below:

    ClassXXX* ClassYYY::create_xxx()

This is also applied when there is a code in xs-adapters like:

    ClassXXX* item = ... ; // get somehow pointer to ClassXXX
    RETVAL = xs::out<>(item);

=item it might contain Perl package name (in form of string or Stash)

In that case SV* pointing to C<undef> is created, and it is blessed into the specified
package name. This is needed to follow standart Perl inheritance model, i.e. respect
when the current class might be derived in Perl or xs-adapter. In other words it
works similar to:

    package My::XXX;

    sub new {
        my $class = shift;
        my $obj = {};
        return bless $obj => $class;
    }

    package My::YYY;
    use base qw/My::XXX;

    my $obj_a = My::XXX->new;
    my $obj_b = My::YYY->new;

=item it might be already blessed Perl object

In that case SV* the pointer to C++ object is attached to the existing SV*, the new
SV* will not be created and the existing SV* will be returned as result of the
operation.

The typical use case is C3-mixin and C<next::method> awareness. It is similar
to the perl code

    sub new {
        my $class = shift;
        my $obj = $class->next::method(@_);
        ...
        return $obj;
    }

Ususally in xs-adapter the C<proto> is obtained via

    ..::new(...)
    PROTO = Stash::from_name(CLASS).call_next(cv, &ST(1), items-1);
    RETVAL = new MyClass();
    // ParseXS from XS::Framework will invoke xs::out automatically

=item it might be something else (ArrayRef or HashRef)

In that it behaves the same as with the empty C<proto>, but instead of
using C<undef> as base value to bless the default typemap's package(),
it uses the provided object as base to bless. This is similar to

    return bless {} => 'MyClass';  # or:  return bless [] => 'MyClass'

This might be useful when B<it is known> that the class will be extended I<from
Perl>, i.e. to avoid L<XS::Framework::obj2hv> invocation in Perl descedant
class.

=back

If the default behaviour is not desirable, i.e. there is need to return
blessed hashref B<and> tolerate possible descendant classes, then the C<new>
method should be like:

    Myclass* Myclass::new(...) {
        RETVAL = new Myclass(...)
        PROTO = Stash::from_name(CLASS).bless(Hash::create());
    }

Beware of the orded above: the C++ class have to be created first, and only
then Perl SV* wrapper should be created next. If the order is reversed
and C++ class I<throws an exception> in constructor, the C++ object is not
constructed, and there is nothing to attach to Perl SV*; but in the
SV* desctruction it will be detected (invalid object reference), and the
corresponding warning will be shown.

 view all matches for this distribution
 view release on metacpan -  search on metacpan

( run in 0.519 second using v1.00-cache-2.02-grep-82fe00e-cpan-2c419f77a38b )