Scroll to navigation

XS::Object::Magic(3pm) User Contributed Perl Documentation XS::Object::Magic(3pm)

NAME

XS::Object::Magic - Opaque, extensible XS pointer backed objects using "sv_magic"

VERSION

version 0.05

SYNOPSIS

        package MyObject;
        use XS::Object::Magic;
        sub new {
                my $class = shift;
                # create any object representation you like
                my $self = bless {}, $class;
                $self->build_struct;
                return $self;
        }
        # or using Moose
        package MyObject;
        use Moose;
        sub BUILD {
                shift->build_struct;
        }
        # then in XS
        MODULE = MyObject  PACKAGE = MyObject
        void build_struct (SV *self)
                PREINIT:
                        my_struct_t *thingy;
                CODE:
                        thingy = create_whatever();
                        /* note that we dereference self first. This
                         * can be done using an XS typemap of course */
                        xs_object_magic_attach_struct(aTHX_ SvRV(self), thingy);
        void foo (SV *self)
                PREINIT:
                        my_struct_t *thingy;
                INIT:
                        thingy = xs_object_magic_get_struct_rv(aTHX_ self);
                CODE:
                        my_struct_foo(thingy); /* delegate to C api */
        /* using typemap */
        void foo (my_struct_t *thingy)
                CODE:
                        my_struct_foo(thingy);
        /* or better yet */
        PREFIX = my_struct_
        void
        my_struct_foo (thingy)
                my_struct_t *thingy;
        /* don't forget a destructor */
        void
        DESTROY (my_struct_t *thingy)
                CODE:
                        Safefree(thingy);
                        /* note that xs_object_magic_get_struct() will
                         * still return a pointe which is now invalid */

DESCRIPTION

This way of associating structs with Perl space objects is designed to supersede Perl's builtin "T_PTROBJ" with something that is designed to be:

The association of the pointer using "sv_magicext" can be done on any data type, so you can associate C structs with any representation type.

This means that you can add pointers to any object (hand coded, Moose or otherwise), while still having instance data in regular hashes.

The C pointer is neither visible nor modifiable from Perl space.

This prevents accidental corruption which could lead to segfaults using "T_PTROBJ" (e.g. "$$ptr_obj = 0").

C API

When called on the object reference it will check that the "sv" is a reference, dereference it and return the associated pointer using "xs_object_magic_get_struct".

Basically the same as "xs_object_magic_get_struct(aTHX_ SvRV(sv)" but croaks if no magic was found.

Note that storing a "NULL" pointer will not cause an error.

Fetches the pointer associated with "sv".

Returns "NULL" if no pointer is found. There is no way to distinguish this from having a "NULL" pointer.

Fetches the appropriate "MAGIC" entry for the struct pointer storage from "sv".

This lets you manipulate "mg-"mg_ptr> if you need to.

Associates "ptr" with "sv" by adding a magic entry to "sv".
Convenience function that creates a hash object blessed to "stash" and associates it with "ptr".

Can be used to easily create a constructor:

        SV *
        new(char *class)
                CODE:
                        RETVAL = xs_object_magic_create(
                                (void *)test_new(),
                                gv_stashpv(class, 0)
                        );
                OUTPUT: RETVAL
    
Returns 1 if the SV has XS::Object::Magic magic, 0 otherwise.
Returns 1 if the SV references an SV that has XS::Object::Magic magic, 0 otherwise.

This lets you write a quick predicate method, like:

    void
    my_struct_has_struct (self)
            SV *self;
            PPCODE:
                    EXTEND(SP, 1);
                    if(xs_object_magic_has_struct_rv(aTHX_ self))
                            PUSHs(&PL_sv_yes);
                    else
                            PUSHs(&PL_sv_no);
    

Then you can check for the existence of your struct from the Perl side:

    if( $object->has_struct ) { ... }
    
Removes the XS::Object::Magic magic with attached pointer "ptr" from the given SV. Returns the number of elements removed if something is removed, 0 otherwise.

Supplying NULL as "ptr" will result in all XS::Object::Magic magic being removed.

Likes "xs_object_magic_detach_struct", but takes a reference to the magic-containing SV instead of the SV itself. The reference to the SV is typically $self.

Returns 0 if the SV is not a reference, otherwise returns whatever "xs_object_magic_detach_struct" returns.

"ptr" is passwd to xs_object_magic_detach_struct unmodified.

TYPEMAP

The included typemap provides a "T_PTROBJ_MG" entry which only supports the "INPUT" conversion.

This typemap entry lets you declare methods that are invoked directly on the associated pointer. In your own typemap add an entry:

        TYPEMAP
        my_pointer_t *  T_PTROBJ_MG

and then you can use "my_pointer_t" as the argument type of the invocant:

        I32
        method (self)
                my_pointer_t *self;
                CODE:
                        ...

Note that there is no "OUTPUT" conversion. In order to return your object you need to use ST(0) or some other means of getting the invocant.

SUPPORT

Bugs may be submitted through the RT bug tracker <https://rt.cpan.org/Public/Dist/Display.html?Name=XS-Object-Magic> (or bug-XS-Object-Magic@rt.cpan.org <mailto:bug-XS-Object-Magic@rt.cpan.org>).

AUTHOR

יובל קוג'מן (Yuval Kogman) <nothingmuch@woobling.org>

CONTRIBUTORS

  • Florian Ragwitz <rafl@debian.org>
  • Jonathan Rockway <jon@jrock.us>
  • Karen Etheridge <ether@cpan.org>
  • Emmanuel Rodriguez <emmanuel.rodriguez@gmail.com>
  • Jeremiah C. Foster <jeremiah@jeremiahfoster.com>

COPYRIGHT AND LICENCE

This software is copyright (c) 2009 by יובל קוג'מן (Yuval Kogman).

This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.

2024-03-09 perl v5.38.2