note jeroenes Maybe the casting of entry to an SV does the trick. newRC_inc can also take an AV as input. <p> <b>Update</b>: Tested the following... too lazy for XS, so Inline: <code> use Data::Dumper; $ref = testRV( 'monks' ); print Dumper( $ref ); use Inline C => <<'END_OF_C' SV* testRV(char* dirname){ SV* record[2]; AV *entry, *ret_val; SV* retarray; int i = 0; ret_val = newAV(); while (i<10) { record[0] = newSVpv(dirname, 0); record[1] = newSViv(i); entry = av_make(2, record); av_push(ret_val, newRV_inc( entry)); i++; } retarray=newRV_noinc( ret_val); return retarray; } END_OF_C #results in: $VAR1 = [ [ 'monks', '0' ], [ 'monks', 1 ], [ 'monks', 2 ], ... </code> In other words, just a 2D array as you wanted. BTW, Inline didn't complain about the AV* 's, but than, maybe those warnings were suppressed? <p> So I think Fastolfe has pinpointed it, when he noticed you exc'd the sub in array context... <p> If you really want to output arrays from C, you need to push your items on the stack. 123361 123361