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


in reply to Re: Is this a sane/safe way to pass an aref into a C function? (XS<Perl)
in thread Is this a sane/safe way to pass an aref into a C function?

Thanks tye, that's great!

I was trying similar things, but did not realize pack was required. This is far easier and less error-prone as you said (as well it saves me from having to wrap one C function with another as this way, I can pass the data directly to the original function), but I am thankful that I was able to learn how to pass in perl variables into a C function, even though I'm going to revert to using this method instead:

use warnings; use strict; use feature 'say'; use Inline 'C'; my @b = (1..3, 253..255); my $x = pack "V0C*", @b; check($x, length($x)); __END__ __C__ #include <stdio.h> #include <stdint.h> void check(unsigned char* n, int len){ int i; for(i=0; i<len; i++){ printf("%d\n", n[i]); } }

Output:

1 2 3 253 254 255

Of course, in the real code, I perform error checking.

Replies are listed 'Best First'.
Re^3: Is this a sane/safe way to pass an aref into a C function? (XS<Perl)
by Marshall (Canon) on Jan 23, 2017 at 03:44 UTC
    Good thread.
    I tried to get this code working with Active State 5.20, but I don't have right "formula" to do that on my current little laptop. Is there a FAQ on this? What compiler is necessary, etc...?

    PS: I think your check() would be more "C like" coded something like this:

    void check(unsigned char* n, int len) { while (len--) { printf ("%d\n", *n++); } }
    The variable: int i is unnecessary. With the C calling convention on 32 bit machine, check() is passed a 32 bit pointer to n (pointer to an array of unsigned bytes) and a 32 bit signed integer, len on the stack. These are copies for the subroutine to modify and use as it wishes.

    This n[i] syntax is often coded by the compiler as (n i*size_of_n) plus base address. Whereas n++ is coded as n plus the size_of_n.