Thanks to Sisyphus & Eric Wilhelp for excellent answers to my question !!

I have another (I think the answer is no, but I just wanted to be sure since I could not find anything in the mailing list) :

Is it possible to access global variables declared in perl space from an Inlined C function ?

Thanks !
Nitin

Sisyphus wrote:
Nitin Madnani wrote:

An interesting question - and one I was unable to answer off the top of my head. Here's something that works. I've used a different script layout ... but that's not part of the solution .... it's just that I always arrange things like this :-)

use warnings;
use Inline C => Config =>
    BUILD_NOISY => 1; # to make sure we get to
                      # see compiler warnings

use Inline C => <<'END_OF_C_CODE';

void add_one(AV * arri) {
int leni, lenj, i, j, t;
AV * arrj;
SV ** elemi, **elemj;

leni = av_len(arri) + 1;
for(i = 0; i < leni; ++i) {
   elemi = av_fetch(arri, i, 0);
   if(elemi == NULL) croak("Got a NULL in arri");
   arrj = (AV*)SvRV(*elemi);
   lenj = av_len(arrj) + 1;

   for(j = 0; j < lenj; ++j) {
      elemj = av_fetch(arrj, j, 0);
      if(elemj != NULL) {
        t = (int)SvIV(*elemj);
    t++;
    sv_setiv(*elemj, t);
        }
      else croak("Got a NULL in arrj");
      }
   }

}

void get_arr(SV* arr) {
int i, leni;
AV * arref;
SV ** elem;

arref = (AV *)SvRV(arr);
leni = av_len(arref) + 1;
for(i = 0; i < leni; ++i) {
   elem = av_fetch(arref, i, 0);
   if(elem != NULL) printf("%d ", (int)SvIV(*elem));
   else croak("Got a NULL in get_arr()");
   }
printf("\n");
}


END_OF_C_CODE

my @one = (1,2,3,4);
my @two = (10,20,30,40,50);
my @three = (19,29,39,49,59,69);
my @numarr = ([EMAIL PROTECTED], [EMAIL PROTECTED], [EMAIL PROTECTED]);

get_arr([EMAIL PROTECTED]);
get_arr([EMAIL PROTECTED]);
get_arr([EMAIL PROTECTED]);
add_one([EMAIL PROTECTED]);
print "@[EMAIL PROTECTED]@three\n";

__END__

Note that 'add_one()' takes an AV* as its argument. I've done 'get_arr()' just as a simple example of how to get at the values when the array reference is passed as an SV* (instead of an AV*).

There are no doubt inefficiencies in both subs (eg unnecessary copying) - but it's a start. Hope it helps.

Cheers,
Rob

Reply via email to