Thank,
Regards
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;
}
}
--
---
==========================================================================
Patrick DUPRÉ | |
Department of Chemistry | | Phone: (44)-(0)-1904-434384
The University of York | | Fax: (44)-(0)-1904-432516
Heslington | |
York YO10 5DD United Kingdom | | email: [EMAIL PROTECTED]
==========================================================================
--
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
http://learn.perl.org/