Tim Pushor <[EMAIL PROTECTED]> writes: >Hi Nick, > >Nick Ing-Simmons wrote:
Sorry for delay in reply... >> >I can see your point. The tie scheme looks like a clean way to implement >what I was trying to do in the first place. For now, what I am doing is >taking a reference to a scalar, then in the C functions, before I use >the double, I take the value of the scalar, stuff it in the double, then >after the C operation put it back into the scalar. The only problem with >this is that I don't really understand how the reference count stuff >really works in perl. I have a feeling that since I am holding onto the >reference (actually, I am not - I found that this didn't work for some >reason) I need to bump the reference count. > >So now come to think of it, what I am really doing is storing the value >of the scalar itself, like: > >Perl: > >$key=1; store (\$key); > >print "$key\n"; > >cfunc(); Your cfunc() takes a value in code below. > >print "$key\n"; > >C: > >/* Global */ > >SV *perlvar; > >void store (SV *ref) { > perlvar=SvRV(ref); >} Perl functions are passed by reference, so you don't _need_ to accept a reference like that. But it is probably safer to do it that way. Bumping the refcount is easy: void store (SV *ref) { perlvar=SvREFCNT_inc(SvRV(ref)); } > >void cfunc (double val) { > sv_setnv(perlvar,val); >} With this scheme should really have some way to mark SV as no longer needed somehow (to decrement REFCNT again). > >* When I tried to save the reference in a global and access it later it >didn't work. How didn't it work? >Is this becuase I didin't bump the reference count? Most likely, but if you still have the variable in scope (to be able to print it), then it should still be there for cfunc() to set. So what was the fail mode? >What >are the downsides to the way I am doing it now (I *know* there must be a >downside). Hope not because lots of Tk stuff works like that ;-) (Tk uses tie (or low level MAGIC) when perl setting value must cause immediate update of GUI, but in other cases it just saves SV.) > >>However collecting things in to an "execution context" as suggested >>is likely to be cleaner. >> >> >> >I don't really follow that. What I think the person I was agreeing with meant was pass each of your C functions a pointer to a struct, and then keep all the house keeping things in the struct. So the struct might contain: handle to the open database SV * to the perl SV error message/code from library Then when you set one of these up it returns (blessed reference to) the struct as a perl "object". my $token = store($db,\$key); cfunc($token); These can then be make to look like methods: store becomes 'new' (or TIESCALAR) and cfunc is the "FETCH" method. > >>A clean scheme is put a C "struct" in the string slot of an SV. >>If this is just opaque data that is all you need to do, and perls REFCNT >>will free string at right time. >> >>To get at sub-fields from perl side with provide XS "methods" as accessors >>or (if struct isn't too complex) accessors in perl code that use >>pack/unpack on the data. >> >> >> >I think this may be overkill. > > I really like your TIE idea. Mostly because there is nothing special to >do on the C side, where I really need the performance. From perl, I can >call the isam routine repeatedly and there is no copying the double in >and out of the perl scalar. Now if I could only figure it out ;-) > >Thanks for your feedback, I truly appreciate it. > >Tim