<[EMAIL PROTECTED]> writes: >Hi Nick, > >my name is Doug Brann, and you don't know me. I'm sorry to be mailing this to >you directly, but I've tried posting to the perl-xs newsgroup several times >without success. It's the first time I've ever tried posting to a newsgroup, so >I don't know if there is some problem with the news server, or the idiot trying >to post (me, that is). If you don't have the time to answer this, if you would >please forward it to the newsgroup, I'd be grateful. > >Anyhow, here's my problem: > >I have a perl script that is doing something like: > >%data = &Reader::new("file");
You are only passing "file" and not the class. Did you mean: %data = Reader->new("file"); > >foreach (keys %data) { > print ("$_ is of type $data{$_}); >} > >in the foreach block, the response is UNKNOWN, when I'm hoping it will say >ARRAY. There are syntax errors in that - at least a missing ". >It I get the hash key out, but not the correct array type. When I try to >access the array, I get fatal errors in the script. > >Here's a chunk of the offending xs code: > >void >new (CLASS, filename) > char *CLASS > char *filename >PREINIT > AV *data = NULL; > SV *sv = NULL; > double *data_ptr; > unsigned int count; > unsigned int size; > FILE = *file; > char name[1024]; /* name is only 1023 long */ > unsigned int i; >PPCODE: > if((file=fopen(filename, "rb")) == NULL) { As you declared this as taking two args (CLASS and filename) and only passed one I would expect this to fail. > printf("couldn't open %s\n", filename); > XSRETURN_UNDEF; You would probably be better off with XSRETURN(0); // return empty list Otherwise you have done %data = (undef); > } > > count = 0; > name[1023] = '\0'; /*need a null terminator */ > done = 0; > while (feof(file)){ Surely you mean while (!feof(file)) ? > /* read in the name */ > fread(&name, 1, 1023, file); You could look at the count of items returned and use 0 items rather than : > if(feof(file)) { // wrong sense again. > continue; > } > > /* now get the size */ > fread(&size, 4, 1, file); fread(&size, sizeof(size), 1, file); // would be safer. > > /* get some memory and the data */ > data_ptr = (double*)safemalloc(sizeof(double) * size); > if(data_ptr == NULL) { > printf("couldn't get memory"); > XSRETURN_UNDEF; > } > > fread (data_ptr, sizeof(double) * size, 1, file); fread(data_ptr, sizeof(double), size, file); // intended use of fread > data = (AV*) sv_2mortal((SV*)newAV()); I don't think the AV should be mortal... > av_extend(data, size); > > for (i = 0; i < size; i++) > /* boy I wish I could fread the data straight into */ > /* an AV array without this step !! */ // You could read it into a "pack-ed" string. > av_store(data, i newSVnv(data_ptr[i])); > } > > XPUSHs(sv_2mortal(newSVpv(name, 1024))); I am unclear about the length there - is this a normal C string? > XPUSHs(sv_2mortal(newRV_noinc((SV*)data))); The RV should be mortal, but as AV is as well, the AV will be freed from under it... > count++; > safefree(data_ptr); > } /* while */ > >XSRETURN(count *2); > > >Can you help me? I've looked in the archives of the newsgroup and found a >similar problem, and tried duplicating the code, to no avail. The XS/perl parts look okay. It is your use of stdio that is dodgy. > >specifically I read "Adding an array as a hash entry - Cloutier, Christian >Date: 05-29-03 11:07" > >Thanks in advance for any help you can give. > >-Doug Brann > > > > > >------------------------------------------------------------ >This email was sent from Netspace Webmail: http://www.netspace.net.au