[This is copied and edited from a msg I just posted to c.l.p.misc.]
I am creating a module that connects Perl to a C library, where the C
library exposes all of it's data via hashes. The C hashes need to
stay "live" (I can't just copy their values back and forth into a Perl
copy of the hash). Perl's tied hashes are the answer, but I'm having
some trouble implementing.
I started out copying *DBM_File, which lets Perl create a C object
pointer, store it in an SV (sv_setref_pv), which then gets tie()'d in
Perl, and so calls FETCH, STORE, etc. in C. That works nicely, for C
objects *created and hooked up via the Perl tie() call*.
The problem I'm facing is that I've got lots of C objects that already
exist, and various C functions that will return references to these
objects back to Perl. I need to be able to "wrap" the existing C
objects as a self-tied object and then pass them back to Perl. That's
where I'm stuck.
What I'm trying now is creating the Perl HV, associating it with my
object, and adding tie magic to the HV so that my routines will be
called:
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
I know I'm doing something wrong here because none of TieTest_len,
TieTest_clear, TieTest_get, or TieTest_set ever get called, and yet
the program segfaults. vtbl_TieTest and vtbl_TieTestelem are
patterned after vtbl_pack and vtbl_packelem. (Commenting out all the
magic stuff doesn't segfault, so most of the i/f works.)
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?
Thanks,
-- Ken
[1] <http://www.mail-archive.com/perl-xs%40perl.org/msg00081.html>