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

Reply via email to