Patrick Dupre wrote: > Hello, > > I am trying to pass a array of references on array to a c subroutine: > my @set_2d = ([0.0, 1.0], [1.1, 2.2], [3.1, 4.4]) ; > test::test([EMAIL PROTECTED]) ; > > in xs I put: > > typedef double floatArray ; > > void * floatArrayPtr (int num) { > SV * mortal ; > mortal = sv_2mortal (NEWSV (0, num * sizeof (floatArray))) ; > return SvPVX (mortal) ; > } > > double > spectrum_2d (avref) > AV * avref > PREINIT: > int len, ncols; > int i, j ; > SV ** elem ; > floatMatrix *matrix ; > AV** row ; > CODE: > len = av_len (avref) + 1 ; > printf ("spectrum_2d: %d\n", len) ; > ncols = 2 ; > matrix = floatMatrixPtr (len) ; > for (i = 0 ; i < len ; i++) { > matrix [i] = floatArrayPtr (ncols) ; > } > for (i = 0 ; i < len ; i++) { > row = av_fetch (avref, i , 0) ; > if (row =! NULL) { > for (j = 0 ; j < ncols ; j++) { > elem = av_fetch (*row, j , 0) ; > if (elem == NULL) { > matrix [i] [j] = 0 ; > } > else { > matrix [i] [j] = SvNV (*elem) ; > } > } > } > } > RETVAL = 0 ; > OUTPUT: > RETVAL > > But it does not work, > If somebody could tell me what is wrong !
OK, the main problem is that row = av_fetch(avref, i , 0); returns a **SV that is a reference to an array, not an array. So when you go ahead to write elem = av_fetch (*row, j , 0); you're passing a *SV instead of a *AV. You need to dereference it like rowref = av_fetch(avref, i , 0); row = (AV *)SvRV(*rowref); elem = av_fetch (row, j , 0); Below is a working XS file. HTH, Rob #include "EXTERN.h" #include "perl.h" #include "XSUB.h" typedef double floatArray; void *floatArrayPtr(int num) { SV *mortal = NEWSV(0, num * sizeof(floatArray)); sv_2mortal(mortal); return SvPVX(mortal); } typedef floatArray *floatMatrix; void *floatMatrixPtr(int num) { SV *mortal = NEWSV(0, num * sizeof(floatMatrix)); sv_2mortal(mortal); return SvPVX(mortal); } MODULE = Arrays PACKAGE = Arrays void spectrum_2d(avref) AV *avref PREINIT: int nrows, ncols; int i, j; AV *row; SV **rowref, **elem; floatMatrix *matrix; CODE: if (avref == NULL || SvTYPE(avref) != SVt_PVAV) return; nrows = av_len(avref) + 1; matrix = floatMatrixPtr(nrows); for (i = 0; i < nrows; i++) { rowref = av_fetch(avref, i, 0); if (rowref == NULL || !SvROK(*rowref)) { matrix[i] = NULL; continue; } row = (AV *)SvRV(*rowref); ncols = av_len(row) + 1; matrix[i] = floatArrayPtr(ncols); for (j = 0; j < ncols; j++) { elem = av_fetch(row, j , 0); if (SvNOK(*elem)) matrix[i][j] = SvNV(*elem); else if (SvIOK(*elem)) matrix[i][j] = SvIV(*elem); else matrix[i][j] = 0; } } -- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED] http://learn.perl.org/