XS::Object::Magic - Opaque, extensible XS pointer backed objects using sv_magic
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:
T_PTROBJ
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.
sv_magicext
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).
$$ptr_obj = 0
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.
sv
xs_object_magic_get_struct
Basically the same as xs_object_magic_get_struct(aTHX_ SvRV(sv) but croaks if no magic was found.
xs_object_magic_get_struct(aTHX_ SvRV(sv)
Note that storing a NULL pointer will not cause an error.
NULL
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.
MAGIC
This lets you manipulate mg-mg_ptr> if you need to.
mg-
Associates ptr with sv by adding a magic entry to sv.
ptr
Convenience function that creates a hash object blessed to stash and associates it with ptr.
stash
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 from the given SV. Returns 1 if something is removed, 0 otherwise.
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.
xs_object_magic_detach_struct
$self
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.
T_PTROBJ_MG
INPUT
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:
my_pointer_t
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.
OUTPUT
ST(0)
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.
To install XS::Object::Magic, copy and paste the appropriate command in to your terminal.
cpanm
cpanm XS::Object::Magic
CPAN shell
perl -MCPAN -e shell install XS::Object::Magic
For more information on module installation, please visit the detailed CPAN module installation guide.