Ken MacLeod wrote:
> MyObject *my_object; // Initialized elsewhere
>
> MGVTBL vtbl_TieTest = { 0, 0, TieTest_len, TieTest_clear, 0 };
> MGVTBL vtbl_TieTestelem = { TieTest_get, TieTest_set, 0, 0, 0 };
>
> MODULE = TieTest PACKAGE = TieTest
>
> HV *
> get_my_object()
> CODE:
> MAGIC *mg;
> RETVAL = newHV();
> sv_setref_pv((SV*)RETVAL, "TieTest", my_object);
> hv_magic(RETVAL, NULL, 'P');
> hv_magic(RETVAL, NULL, 'p');
> mg = mg_find((SV*)RETVAL, 'P');
> mg->mg_virtual = &vtbl_TieTest;
> mg = mg_find((SV*)RETVAL, 'p');
> mg->mg_virtual = &vtbl_TieTestelem;
> OUTPUT:
> RETVAL
Firstly I think you should avoid self-ties - they really don't work.
I've set up ties from C with no problems, but I havn't done it by
diddling with the vtbls directly - I suspect you are in uncharted
territory here. Here's the way I have done it:
hash = newHV();
tie = newHV();
tieref = newRV_noinc((SV *)tie);
stash = gv_stashpv("Sun::Solaris::Kstat::_Stat", TRUE);
sv_bless(tieref, stash);
hv_magic(hash, (GV *)tieref, 'P');
Then just define the tiehash methods as XS functions, e.g.
SV*
FETCH(self, key)
SV* self;
SV* key;
If you need to hide a pointer to a C struct inside the hash you can do
it like this (kc is the C struct pointer):
/* Create a place to save the KstatInfo_t structure */
kcsv = newSVpv((char *)&kc, sizeof (kc));
sv_magic(SvRV(RETVAL), kcsv, '~', 0, 0);
SvREFCNT_dec(kcsv);
You can then retrieve it with:
mg = mg_find(SvRV(self), '~');
kc = *(kstat_ctl_t **)SvPVX(mg->mg_obj);
> The recent thread, "XS self-tied AV goes into recursive frenzy on
> FETCH"[1] seems to hit real close to the mark. Is there a self-tied
> hash example similar to that available somewhere?
The above code is takne from the Solaris::Kstat module, available from
CPAN.
--
Alan Burlison
Solaris Kernel Development, Sun Microsystems