I'm trying to build an extension to port an arbatrary complex data structure
to Perl.  Up till now, I'm converting booleans, numbers and strings as
scallars, and entire arrays of the above.  Now I'm trying to tackle nested
arrays.

I started by writing a C function to convert the individual data types to
Perl SVs, and a second XS function to return an array of any data, which
simply enumerated the elements and passed them through the above C filter.

To do nested arrays, the plan was to implement it recursively, by making a
callback from the C function to the XS.  Everything *seems* to be
implemented fine, except that I keep getting the above error when trying to
do @perlar=GetArray($ptrref_to_nested_array)

To debug, I used a data structure as follows

ARRAY1 -->42-->"Hello, world!"-->6.54--> -7 -->"42"-->ARRAY2-->1
                                                        |
                                                        |-> "42"
                                                        |-> "Hello!"

I set a line to dump the SVs being pushed onto the stack from GetArray.  The
output looks healthy (it's after sv_2mortal-ing them):

SV = NV(0x19363d4) at 0x1b275a4
  REFCNT = 1
  FLAGS = (TEMP,NOK,pNOK)
  NV = 42
SV = PV(0x1b269e4) at 0x1b274cc
  REFCNT = 1
  FLAGS = (TEMP,POK,pPOK)
  PV = 0x1b41bdc "Hello, World!"\0
  CUR = 13
  LEN = 14
SV = NV(0x19363dc) at 0x1b274c0
  REFCNT = 1
  FLAGS = (TEMP,NOK,pNOK)
  NV = 6.54
SV = NV(0x19363e4) at 0x1b27478
  REFCNT = 1
  FLAGS = (TEMP,NOK,pNOK)
  NV = -7
SV = PV(0x1b26a44) at 0x1b27490
  REFCNT = 1
  FLAGS = (TEMP,POK,pPOK)
  PV = 0x1b41f64 "42"\0
  CUR = 2
  LEN = 3
SV = PV(0x1b26aa4) at 0x1b27514
  REFCNT = 1
  FLAGS = (TEMP,POK,pPOK)
  PV = 0x1b41774 "42"\0
  CUR = 2
  LEN = 3
SV = PV(0x1b26a98) at 0x1b275bc
  REFCNT = 1
  FLAGS = (TEMP,POK,pPOK)
  PV = 0x1b41854 "Hello!"\0
  CUR = 6
  LEN = 7
SV = RV(0x195b424) at 0x1b27520
  REFCNT = 1
  FLAGS = (TEMP,ROK)
  RV = 0x1b275b0
SV = NV(0x1936404) at 0x1b2755c
  REFCNT = 1
  FLAGS = (TEMP,NOK,pNOK)
  NV = 1

I really don't know what I'm doing wrong...  The relevant sections of code
are:

(from C conversion function: SV* newSVval(cx,val) )
...
        if (!(ValToObj(cx,v,&obj))) {
            return &PL_sv_undef;
        }
        if (ArrayObj(cx,obj)) {
            AV* av;
            dSP ;
            int count;
            int i;
            ENTER ;
            SAVETMPS ;
            PUSHMARK(SP) ;
            XPUSHs(sv_2mortal(sv_setref_pv(newSV(0), Nullch, cx)));
            XPUSHs(sv_2mortal(sv_setref_pv(newSV(0), Nullch, obj)));
            PUTBACK ;
            count=call_pv("GetArray", G_ARRAY);
            SPAGAIN ;
            av=newAV();
            av_fill(av,count);
            for (i=0;i<count;i++) {
                av_store(av,count-i,newSVsv(POPs));
            }
            PUTBACK ;
            FREETMPS ;
            LEAVE ;
            return newRV_noinc((SV*)av);
        } else {
            return &PL_sv_undef;
        }

(GetArray)
GetArray(cx, obj)
        Context*  cx
        Object*   obj
######################################################################
    PREINIT:
        int i,len;
        val rval;
    PPCODE:
        if (!(ArrayObj(cx,obj))) {
            XSRETURN_UNDEF;
        }
        if (!(ArrayLen(cx,obj,&len))) {
            XSRETURN_UNDEF;
        }
        EXTEND(SP,len);
        for (i=0;i<len;i++) {
            if (GetElement(cx,obj,i,&rval)) {
                SV* tmp=sv_2mortal(newSVval(cx,rval));
                sv_dump(tmp);
                XPUSHs(tmp);
            } else {
                XPUSHs(&PL_sv_undef);
            }
        }

You can see where the above dump came from.

The test environment (using Test::More) for this is:
isnt(GetArray($cx,$testar),undef,"Got something useful from GetArray");
my @nperlar=GetArray($cx,$testar);
Dump([EMAIL PROTECTED]);

The output (excluding the sv_dump) is:
ok 16 - Got something useful from GetArray
Bizarre copy of CODE in aassign at t\advarray.t line 37.
# Looks like you planned 19 tests but only ran 16.
# Looks like your test died just after 16.

This has been driving me nuts for a week now.  If anyone could help I'd be
greatly appreciative.

Thanks!
  Issac

-- 
Mirimar Networks
www.mirimar.net
Email, Hosting, Design, Programming, SysAdmin
Complete Web Solutions

Key ID: 0x6F9522D8
Fingerprint: A8BA 9617 EF3B CCAC 3B29 B869 EDB1 0589 6F95 22D8


Reply via email to