Beefy Boxes and Bandwidth Generously Provided by pair Networks
good chemistry is complicated,
and a little bit messy -LW

Tie::PureDB is out

by PodMaster (Abbot)
on Apr 10, 2003 at 12:22 UTC ( #249588=note: print w/replies, xml ) Need Help??

in reply to Re: panic: leave_scope inconsistency. (need help creating Tie::PureDB) (less XS)
in thread panic: leave_scope inconsistency. (need help creating Tie::PureDB)

I have taken your advice, and after some tomfoolery, I have finished writing the xs.
I still feel this is a really really ghetto way to go about it, but that's how it goes
;( I have asked the author of Extending and Embedding perl to take a look at the panic.
I'm not holding my breath, but it'd be real slick if I got that version working ).

Anyway, check it out,
The pod is scarce for now, but if you're curious how the interface works just look at the tests.

Thanks for the strategy.
I'd appreciate if people would give it a test run before I add the pod and release it on CPAN (aka feedback).

BTW -- all XS programmers should use Safefree and New instead of malloc and free, in addition to PTR2IV and INT2PTR.

MJD says you can't just make shit up and expect the computer to know what you mean, retardo!
I run a Win32 PPM repository for perl 5.6x+5.8x. I take requests.
** The Third rule of perl club is a statement of fact: pod is sexy.

Replies are listed 'Best First'.
Re: Tie::PureDB is out (thanks/PV)
by tye (Sage) on Apr 10, 2003 at 15:55 UTC

    Thanks for the notes on proper allocation/free and converting between pointers and integers.

    The approach I outlined is very similar to T_PTROBJ, both of which are about the best you can do (which isn't very good in my book) if you need to have Perl deal with data structures that Perl does not allocate.

    Since you can use Safefree/New, then you are allocating the space and you can have a better interface by having Perl allocate the space instead.

    SV * xs_new( ... ) CODE: size_t len= number_of_bytes_needed(); sv_grow( RETVAL, len ); // "malloc" void *buf= SvPV( RETVAL ); size_t used= constructor( buf, len, ... ); // Tell Perl how much of the buffer is actually in use: SvCUR_set( RETVAL, used );
    Then you end up with a Perl scalar that contains a string value which is the contents of the buffer you allocated and Perl will be happy to free() it when it needs to and you don't even need a DESTROY method for that anymore. You can also access the buffer data directly from Perl now in case there are simple things you want to do that don't really require that XS code be written.

    You can get the pointer to this buffer by simply using "char *" arguments in other XS functions.

    And if you want a destroy method for other reasons, then I'd still do the bless and DESTROY in Perl code rather than in XS.

    Be aware that passing this string value around directly in Perl can easily result in the value being copied (a new buffer malloc()d and the data copied from the old buffer to the new buffer) and that you can modify the buffer from Perl code such that Perl decides to realloc() the buffer which can relocate it in memory (and that both of these things can invalidate some types of data such a buffers that contain pointers into themselves).

    Note that the value is not copied when you use the string as an argument to a function but that typical Perl functions include my $buf= shift(@_); or my( $buf, ... )= @_; which is where the copy takes place. So using the string directly in an XS function with a parameter type of "char *" works great.

    I realize that PodMaster probably knows most or all of this, but I include this information for others that might read this node.

    So you might want to wrap this string up as an object so passing around the object will just be copying references to the string (or references to some data structure that contains the string) and the string itself won't get copied.

    Doing that means that you have an extra dereference required in your methods. You can do that in Perl, but if that is the only bit of "Perl written in C" that you need for that method, you might just do it all in XS. The big problems with writing "Perl in C" for XS is if you are creating things on the stack (everyone gets the mortal/refcount stuff wrong even though it isn't that complicated/confusing if you really get your mind around it) or trying to deal with Perl variables that users pass to you (XS code only deals with very vanilla variables and simply breaks in the face of tie or magic or a need for autovivification, etc. -- I've been thinking about croaking on "thinkfirst" in my XS code in future).

                    - tye

Log In?

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://249588]
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others meditating upon the Monastery: (7)
As of 2022-12-01 18:07 GMT
Find Nodes?
    Voting Booth?