jpl has asked for the wisdom of the Perl Monks concerning the following question:
I have an XS module, mostly following the models in Extending and Embedding Perl. I use a T_PTROBJ type, and keep everything I need in a dynamically allocated C structure, whose address is the T_PTROBJ object. But as I add functionality, it's a nuisance to have to keep adjusting the contents of the structure. I'd like to be able to do things that are not so time critical in plain perl, but still get directly to the methods defined in the XS module. If I add an HV * to my C structure, I can initialize it with an anonymous hash that acts somewhat like the usual pure-perl blessed object, for holding (and hiding) arbitrary state information. So my skeletal XS code looks something like
where the stash structure element gives me a place to stash my perl-level state. Then my AddrMatch.pm can do something like#include "EXTERN.h" #include "perl.h" #include "XSUB.h" #include "ppport.h" #include <am_common.h> #include "const-c.inc" MODULE = AddrMatch PACKAGE = AddrMatch INCLUDE: const-xs.inc AddrMatch * new_xs(class, stash) char * class HV * stash PREINIT: AddrMatch *amd; CODE: amd = malloc(sizeof(AddrMatch)); SvREFCNT_inc((SV *) stash); amd->stash = stash; RETVAL = amd; OUTPUT: RETVAL MODULE = AddrMatch PACKAGE = AddrMatchPtr void DESTROY(amd) AddrMatch * amd CODE: SvREFCNT_dec((SV *)(amd->stash)); free(amd); HV * stash(amd) AddrMatch * amd CODE: RETVAL = amd->stash; OUTPUT: RETVAL
So the question (there must be a question in here somewhere) is, can this be done more elegantly in some other way? This isn't too onerous, and it makes it quite easy to change my mind about whether some method is implemented in pure perl, or is worth coding into the XS module. But I'd be happy to do it more simply, if possible.package AddrMatch; sub new { my %state = ( what => "ever" ); my $amd = AddrMatch->xs_new(\%state); return $amd; } # then, later, recover the perl-ish state with package AddrMatchPtr; sub something { my $self = shift; my $state = $self->stash(); my $what = $state->{what}; $state{how} = "now"; }
|
---|
Replies are listed 'Best First'. | |
---|---|
Re: Mixing C and perl
by salva (Canon) on Jan 17, 2012 at 18:32 UTC | |
by jpl (Monk) on Jan 17, 2012 at 18:51 UTC | |
by tsee (Curate) on Jan 17, 2012 at 19:06 UTC | |
by salva (Canon) on Jan 17, 2012 at 22:13 UTC | |
Re: Mixing C and perl
by bulk88 (Priest) on Jan 18, 2012 at 07:09 UTC |