XS::Object::Magic(3pm) | User Contributed Perl Documentation | XS::Object::Magic(3pm) |
XS::Object::Magic - Opaque, extensible XS pointer backed objects using "sv_magic"
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 */
This way of associating structs with Perl space objects is designed to supercede Perl's builtin "T_PTROBJ" with something that is designed to be:
This means that you can add pointers to any object (hand coded, Moose or otherwise), while still having instance data in regular hashes.
This prevents accidental corruption which could lead to segfaults using "T_PTROBJ" (e.g. "$$ptr_obj = 0").
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.
Returns "NULL" if no pointer is found. There is no way to distinguish this from having a "NULL" pointer.
This lets you manipulate "mg-"mg_ptr> if you need to.
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
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 ) { ... }
Returns 0 if the SV is not a reference, otherwise returns whatever "xs_object_magic_detach_struct" returns.
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.
<http://github.com/nothingmuch/xs-object-magic>
Florian Ragwitz, Yuval Kogman
Copyright (c) 2009 Florian Ragwitz, Yuval Kogman. All rights reserved This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
2018-11-01 | perl v5.28.0 |