in reply to Passing a bytestring from Perl to Inline::C as a 2d array

Thank you all for your input.

I know that this problem may be solved in Perl or PDL, but now I am interested in exploring how it can be solved with Inline::C. I need speed, and I need compact.

Next, I see no problem in casting a bytestring using pack from Perl as a way of allocating a block of memory to be used in C as long as the block size is sufficient. That way the block of memory will be under Perl's memory management and garbage collection.

As I understand, you can overrule the Perl type from C by type casting, so the pack bytestring does not have to be an array of pointers.

Now, what is the problem with The "built-in" C 2D array? I should say that is exactly what I want - a 2D table of numbers. However, I will try my own index calculations as suggested.

Here is the code mock-up again - this time in code tags :o).

sub perl_routine { $byte_string = pack "I*", (0) x ( $x_dimension x $y_dimension ); c_function( $byte_string, $x_dimension, $y_dimension ); } void c_function( char *byte_string, int x_dimension, y_dimension ) { int **table = ( int ** ) byte_string; int i, j; for ( i = 0; i < x_dimension, i++ ) { for ( j = 0; j < y_dimension, j++ ) { table[ i ][ j ]++; } } }

Martin

Replies are listed 'Best First'.
Re^2: Passing a bytestring from Perl to Inline::C as a 2d array
by BrowserUk (Patriarch) on Nov 13, 2009 at 11:14 UTC

    pack "I*", (0) x ( $x_dimension x $y_dimension );

    int **table = ( int ** ) byte_string;

      table[ i ][ j ]++;

    That still won't work and cannot be made to work! You will still get segfaults.

    You cannot cast a 1D array point to a 2D array of arrays pointer. Full stop.

    The memory for a 1D array (as produced by pack) is laid out so:

    ----------------------------....--------------------- ...|int1|int2|int3|int4|int4|....|N-3 |N-2 |N-1 |N | ----------------------------....---------------------

    For a 2D array like so:

    ---- ptr | This is the int** ---- ... it points to an array of pointer below ... with one pointer for each of the first dimension --------------------------------------- ptr0|ptr1|ptr2|ptr3|....|Y-2 |Y-1 |Y | Each if these is an int * --------------------------------------- ... And each of those pointer point to contingous 1D arrays of ints ... each the size of the second dimension ... that can (and usually are) distributed at disparate position in me +mory ... and in no particular positions, even before the above block of ram +. --------....-----.....-----...etc |ary4| |ary2| |ary0| --------....-----.....-----...etc

    There is simply no way to cast from one to the other.


    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.
      I think BrowserUk is spot on! There is a problem with the C code and the interface.

      I am still troubled by the whole concept of the OP's approach. Instead of packing some things ("chars") into words for C to access on a byte per byte basis, run some regex or other Perl operation on those "things" and THEN run pack() if you need to! I see no need for 'C' here.

      Perl has a very efficient char per char replacement operator called "tr". And also, 'a' + 1 REALLY does mean "b"! Just like in 'C'. I think that if we get to the real requirement, we will find that Perl will do it just fine. The sub() appears trivial enough that I see no need to go through the hassle of interfacing 2 languages.

        Instead of packing some things ("chars") into words for C to access on a byte per byte basis

        He's not packing "chars". He's packing integers (note the 'I*' pack template). And whilst his sample code shows him just incrementing those integers (which he is initialising to 0), his description points out that he intends to populate the structure with "scores", which he is presumably obtaining from somehwere where they must be accessed via C.


        Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
        "Science is about questioning the status quo. Questioning authority".
        In the absence of evidence, opinion is indistinguishable from prejudice.