Thanks again. This will make my code functional, which is a big step. I only have one gripe(sorry!). The arrays that I will be working with could potentially have thousands of entries. Having to iterate through each element of each array seems like an extremely large waste of time.
I obviously don't understand what it takes to convert a perl reference to a C reference (if it can be done at all), but is it not possible? Or is that just a "Perfect World" scenario? Thanks...Brady -----Original Message----- From: Neil Watkiss [mailto:[EMAIL PROTECTED]] Sent: Monday, June 10, 2002 1:30 PM To: bbcannon Cc: '[EMAIL PROTECTED]' Subject: Re: Instantiating arrays with Inline bbcannon [10/06/02 10:35 -0600]: > I do know the size of the array before hand since I create it in perl > first. I am a rookie when it comes to C, so thanks a million. Right... I meant the C compiler needs to know at compile time. Even if you know, that doesn't mean it will know. For example, ----8<---- use strict; use constant SIZE => 10; use Inline C => <<'END'; AV* mkary(int size) { double foo[size]; } END mkary(SIZE); ---->8---- That will be a compile error. Even though it's obvious to humans that the array "foo" will always have 10 elements in it, the C compiler doesn't know where "size" is coming from, so it doesn't know how big to make foo when it's compiling it. > In the Big Picture, I am just trying to pass a perl array > to C because I can then interface to Matlab's Math and Graphics libraries. One way to get around this is to dynamically generate your C code. But a much simpler way is what I've already suggested. > Is there a more efficient/easy way to send an array or array_ref to Inline > C? This is the best way to do it, I think. The only thing you have to check is that you only accept arrays with numeric types. No nested structures (unless you add code for that explicitly). Note: I haven't tried this code, but it looks okay. You probably want to do something like it. The API leaves something to be desired: it takes an arrayref and returns a list... but you get the idea. ----8<---- use Inline C; my @array = (10, 11, 12); my @xformed = do_something(\@array); __DATA__ __C__ void transform_array(SV* ref) { int i, nelems; double *c_ary; AV *ary; if (SvROK(ref) && SvTYPE(SvRV(ref)) == SVt_PVAV) { ary = (AV*)SvRV(ref); nelems = av_len(ary) + 1; New(0, c_ary, nelems, double); SAVEFREEPV(c_ary); for (i = 0; i < nelems; ++i) { SV *elem, **tmp = av_fetch(ary, i, 0); if (!tmp) croak("Error fetching array index %i", i); elem = *tmp; c_ary[i] = SvNV(elem); } /* Operate on c_ary here. Do whatever it is you need to do */ matlab_foozle(c_ary, nelems); /* Depending on your application, you could either save the values of * 'c_ary' back into 'ref', or you can build a new list to return to * the application. */ for (i = 0; i < nelems; ++i) XPUSHs(sv_2mortal(newSVnv(c_ary[i]))); XSRETURN(nelems); } else croak("Not an array ref"); } ---->8---- Later, Neil
