On Mon, Mar 01, 2004 at 02:19:53AM +0300 Vadim O. Ustiansky wrote: > I am new to XS and have not found the solution to my > problem in either docs or CPAN modules' sources so far. > > I want to implement a perl object as a hash reference > but I want some functionality to be implemented in C > which requires to bind some C struct with this perl > object. The question is how this can be accomplished. > The obvious solution (storing a pointer to the struct > as one of the hash's value) has the obvious objection: > anyone has access to this value at perl level as > $obj->{key} = "whatever"; > or even > delete($obj->{key}); > > Nevertheless the CPAN modules I investigated use either > this approach or they implement all functionality in C. > In the latter case the object is implemented as a reference > to a scalar which holds memory address so perl code like: > $$obj = 0x12345; > may break up all the internal C implementation. > > So my question is whether it is possible to completely hide > C internals from perl level.
Sure it is. You can do it manually: void new (CLASS, ...) char *CLASS; CODE: { c_struct *var; New(0, var, c_struct, sizeof(c_struct)); ... ST(0) = sv_newmortal(); sv_setref_pv(ST(0), CLASS, (void*)var); XSRETURN(1); } This returns a blessed Perl reference (blessed into class CLASS). Dereferencing can be done thusly: void method (obj) SV *obj; CODE: { c_struct *var = (c_struct*)SvIV(SvREF(ovj)); ... } It's more convenient to do that via typemaps. I think you can use the predefined T_PTROBJ for that. Put this into the file typemap: c_struct * T_PTROBJ This simplifies your XS to c_struct * new (...) CODE: { c_struct *var; ... RETVAL = var; } OUTPUT: RETVAL And for input: void method (self) c_struct *self; CODE: ... The typemap file is just a sort of text template that is processed by xsubpp. The idea is always the same. You take the address of a C structure and store it somewhere in an SV, for instance the IV slot. This happens through ordinary C typecasts. Tassilo -- $_=q#",}])!JAPH!qq(tsuJ[{@"tnirp}3..0}_$;//::niam/s~=)]3[))_$-3(rellac(=_$({ pam{rekcahbus})(rekcah{lrePbus})(lreP{rehtonabus})!JAPH!qq(rehtona{tsuJbus#; $_=reverse,s+(?<=sub).+q#q!'"qq.\t$&."'!#+sexisexiixesixeseg;y~\n~~dddd;eval