Hi All,
I'm very much new to Perl XS and embedding perl interpreters in my
programs. (and a complete newbie to the perl language itself!)
Anyway, I'm trying to expose a bunch of C structures stored in a C
hash to perl. So far, I've pretty much got the new, FETCH, EXISTS,
FIRSTKEY and NEXTKEY functions written in my XS file, but I'm hitting
a few problems and banging my head around the STORE function. I've
got a few questions that I hope you all don't mind helping me out with:
For FIRSTKEY and NEXTKEY, I'm a little confused what I should return
back. Do I return the actual HASH, or do I return the key name for
the value?
Currently, I'm returning the HASH, and when doing the following code
in perl, I get the following output:
my $hostserv = new NeoStats::NV("HostServ");
while ( my ($key, $value) = each(%$hostserv)) {
NeoStats::debug("Hostserv Key => $value");
while ( my ($key1, $value1) = each(%$key)) {
NeoStats::debug("HS: $key: $key1 => $value1");
}
}
WARNING Test - Hostserv Key => HASH(0x1a702c0)
WARNING Test - HS: HASH(0x1a68f18): passwd => asasasd
<snip>
As you can see, the "Key is actual a HASH". How do I get the actual
key used rather than this reference (note that FETCH works fine though)
for my second issue with Store, some background. I'm representing my
c Structure as a perl hash, and these structures are stored in either
a C hash, or doubly linked lists. so for example in perl if I do:
$var->{key}->{field} it means I want to retrieve the structure stored
with the "key" and the field from that structure. eg:
typedef struct {
char *field;
char *field1;
}
In my FETCH function I do the following:
hash = (HV*)SvRV(self);
mg = mg_find(SvRV(self),'~');
if(!mg) { croak("lost ~ magic"); }
/* this is the nv_hash we are point at */
nv = (nv_list *)SvIV(mg->mg_obj);
/* get the "key" they want */
k = SvPV(key, klen);
/* search for the key */
data = hnode_find((hash_t *)nv->data, k);
RETVAL = (HV *)perl_encode_namedvars(nv, data);
perl_encode_namedvars does the following:
HV *perl_encode_namedvars(nv_list *nv, void *data) {
HV *ret;
int i =0;
ret = newHV();
while (nv->format[i].fldname != NULL) {
switch(nv->format[i].type) {
case NV_PSTR:
case NV_STR:
hv_store(ret, nv->format[i].fldname,
strlen(nv->format[i].fldname),
newSVpv(nv_gf_string(data,
nv, i), strlen(nv_gf_string(data, nv, i))), 0);
break;
case NV_INT:
case NV_LONG:
hv_store(ret, nv->format[i].fldname,
strlen(nv->format[i].fldname),
newSViv(nv_gf_int(data, nv,
i)), 0);
break;
case NV_VOID:
case NV_PSTRA:
break;
}
i++;
}
return ret;
}
So far, so good, I can get a copy of my C structures in Perl. But
when I want to modify a field in perl, my STORE function never gets
called. eg:
$hostserv->{key}->{field} = "test"
Nothing :(
But if I do:
my $newvar;
$newvar->{field} = "test";
$hostserv->{key} = $newvar;
it works like a dream.
So, can anybody shed any light on what I'm doing wrong?
(I've posted some condensed code here, if you want to see the actual
code I'm working on, its here: http://svn.neostats.net/cgi-bin/
viewvc.cgi/NeoStats/trunk/src/NV.xs?revision=3127&view=markup)
(btw, I've dug though all the examples, such as solaris::kstats etc I
could find, and think with reading the doco, and browsing these
mailing lists, I'm probably doing something stupid, and have confused
myself beyond doubt!)
Thanks
Justin