[foreign] Pointer to fixed-size array: is jexctract's mapping to Java correct?

Jorn Vernee jbvernee at xs4all.nl
Wed Feb 27 19:04:34 UTC 2019


I think the takeaway is that the conversion between array and pointer is 
just less automatic in Java compared to C.

To go from a Pointer to an Array, you call `Pointer::withSize` and give 
it an explicit size. Conversely you can decay an Array to a Pointer by 
calling `Array::elementPointer`.

If I understand your requirements correctly, what you want is 
`Array<Array<Double>>`, where the inner Array<Double> represents an 
`fftw_complex`. E.g. (based on the example from the website):

```
     // The canonical/internal type of fftw_complex
     private static final LayoutType<Array<Double>> fftw_complex_t = 
NativeTypes.DOUBLE.array(2); // an array of 2 doubles

     // allocation helper
     public static Array<Array<Double>> malloc_array(long n) {
         return fftw_malloc(fftw_complex_t.bytesSize() *  
n).cast(fftw_complex_t)
                    .withSize(n); // manually convert pointer type to 
array type
     }

     public static void main(String[] args) {
         long N = 1024;

         Array<Array<Double>> in = malloc_array(N);
         Array<Array<Double>> out = malloc_array(N);
         Pointer<fftw_plan_s> p =  fftw_plan_dft_1d(N,
                 // decay arrays to pointer (happens automatically in C)
                 in.elementPointer(),
                 out.elementPointer(),
                 FFTW_FORWARD,
                 FFTW_ESTIMATE
         );

         ...

         fftw_execute(p);

         ...

         fftw_destroy_plan(p);
         // again, decaying array to pointer
         fftw_free(in.elementPointer());
         fftw_free(out.elementPointer());
     }
```

Where `in` and `out` are actually contiguous blocks of memory, just 
viewed as 'array of array of 2 doubles'.

Jorn

Maurizio Cimadamore schreef op 2019-02-27 18:49:
> On 27/02/2019 16:14, Lev Serebryakov wrote:
>> Hmm. It is correct from point of view of type system, but it is
>> incorrect from point of view of memory layout, when it is translated 
>> to
>> Java verbatim. "pointer to array" is something strange in plain C (see
>> comp.lang.c FAQ 6.12 about it: difference between array and pointer to
>> it is in type, but not in memory layout, as array is second-class
>> citizen in C). It is not pointer-to-pointer, it is equivalent (from
>> memory layout point of view) to array itself, and 
>> Pointer<Array<Double>>
>> looks like double-indirection (if we remember, that Array is fancy 
>> name
>> for Pointer in this case), which is not what this native API expected.
> 
> Not sure I follow. A pointer to an array has a very different layout
> from an array.
> 
> #include <stdio.h>
> 
> typedef int ARR[5];
> 
> int main(void) {
>    printf("sizeof ARR = %d\n", sizeof(ARR));
>    printf("sizeof ARR* = %d\n", sizeof(ARR*));
>    return 0;
> }
> 
> 
> this prints:
> 
> sizeof ARR = 20
> sizeof ARR* = 8
> 
> 
> As expected.
> 
> 
> What I think you are saying is, I believe, that if you have a
> Pointer<Array<X>> you can always flatten it as a Pointer<X>; while
> this is technically correct (the underlying layout is correct), when
> you do the flattening you completely lose track of the fact that the
> memory region is not just a sequence of X - but a sequence _of
> sequence_ of X.
> 
> In your example, I agree that you might want to pass an array of 2048
> double to the function and be happy with it. But, what if you pass an
> array with only _one_ ? Or an array with an _odd_ number of doubles?
> This is allowed if we're just talking about a flattened double* - but,
> semantically speaking, this is NOT what the code says with the
> typedef.
> 
> I tried to write examples along these lines:
> 
> typedef double fftw_complex[2];
> 
> int main(void) {
>    double arr[100];
>    fftw_complex *arg = arr;
>    return 0;
> }
> 
> And I always get some warnings when trying to pass a flattened double
> array as a pointer to double[].
> 
> The code might work at runtime, assuming you are not misusing the API
> (see above, e.g. by passing an odd number of doubles), but this is
> still a potentially unsound operation.
> 
> Maurizio


More information about the panama-dev mailing list