http://qs1969.pair.com?node_id=1180097


in reply to Is this a sane/safe way to pass an aref into a C function?

Hi,

Looks sane to me, but there's a portability issue in that your code requires a C99 compliant compiler.

It therefore won't build for me with any of my Microsoft compilers - though I don't have a recent MS compiler to test with.
(The most recent MS compiler I have is  Microsoft (R) C/C++ Optimizing Compiler Version 14.00.40310.41 for AMD64.)

Even if I pre-declare everything and rewrite your XSub as:
int testing(int channel, SV* byte_ref, int len){ SV ** elem; AV * bytes = (AV*)SvRV(byte_ref); int num_bytes = av_len(bytes) + 1; unsigned char buf[num_bytes]; int i; int x; if (channel != 0 && channel != 1){ croak("channel param must be 0 or 1\n"); } if (! SvROK(byte_ref) || SvTYPE(SvRV(byte_ref)) != SVt_PVAV){ croak("not an aref\n"); } num_bytes = av_len(bytes) + 1; if (len != num_bytes){ croak("$len param != elem count\n"); } for (i=0; i<len; i++){ elem = av_fetch(bytes, i, 0); buf[i] = (int)SvNV(*elem); } /* * here, I'll be passing the char buffer and len * to an external C function. For display, I'll * just print the elements * * if ((spiDataRW(channel, buf, len) < 0){ * croak("failed to write to the SPI bus\n"); * } */ for (x=0; x<len; x++){ printf("%d\n", buf[x]); } }
it still errors out with:
try_pl_1bcb6.xs(10) : error C2057: expected constant expression try_pl_1bcb6.xs(10) : error C2466: cannot allocate an array of constan +t size 0 try_pl_1bcb6.xs(10) : error C2133: 'buf' : unknown size NMAKE : fatal error U1077: 'cl' : return code '0x2' Stop.
I would work around that by dynamically allocating buf (Newxz/Safefree) but perhaps there's another way.

Anyway - it's only an issue when (if) your code meets a compiler that's not C99 compliant.

Cheers,
Rob

Replies are listed 'Best First'.
Re^2: Is this a sane/safe way to pass an aref into a C function?
by stevieb (Canon) on Jan 21, 2017 at 23:05 UTC

    Thanks syphilis, I never thought about cross-compilation!

    This definitely isn't my end result here, but as I said in an earlier reply, I'm kind of just learning C, so that didn't cross my mind.

    As I still to this day write my Perl code to compile on as far back of a version as I possibly can (5.8.x minimum), this is a nice piece of feedback, and another avenue of research I have to do as I pick up on C. Learning C is important to me as I have a lot of hardware-interaction software I want to write.

    Perlmonks++ for being able to post something only somewhat relative to Perl and getting help for other languages. One thing is for certain... I had an easier time picking up on C pointers than I did originally figuring out Perl references, but while I was learning how to master those (perl refs), I had no programming experience whatsoever. However, this pointer-to-pointer thing (**) is a bit elusive still, so that's another "book learnin'" thing I still have to pick up on ;)

    update: Above, I didn't mean learning Perl references was overly difficult (in fact, they're not... they're quite logical). The comparison is unfair; I hadn't done but a lick of coding when I had to figure out refs in Perl, but once I grasped them, references/pointers/whatever-you-want-to-call-them became immediately understandable. So really, learning Perl refs allowed me to understand the concept behind *any* languages that has the concept of the sort.