Uncategorized

Proper way to pass a pointer to numpy’s structured array from Python to C


The main issue comes from a mismatch between the physical representation used by Numpy and the one declared in your C code. Indeed, Numpy arrays in a data-type structure are packed contiguously. Such arrays can be seen as plain C arrays (not pointers). Thus, the C declaration must be fixed consequently:

// Better, but incorrect aligned version (see below)
typedef struct intype {
    int nobs;
    double vals[3];
} intype;

There is another issue: by default fields of a structure are aligned to their size in C. Since sizeof(int) is often 4 on most platforms and sizeof(double) is 8, the double-precision numbers (vals) are aligned in a non-standard way. Compilers typically add some padding to fix this issue. This padding causes another mismatch issue and thus certainly the same result. To solve this, you need to tell the compiler that you want a non-standard packed data structure. There is AFAIK no standard way to do that, but mainstream compilers (GCC, Clang and MSVC) support the the #pragma pack directive:

#pragma pack(push, 1)
typedef struct intype {
    int nobs;
    double vals[3];
} intype;
#pragma pack(pop)

For the types to match between the C code and Numpy, the size of the types must, at least, be the same. That is indata.itemsize in Python must be equal to sizeof(intype) in C.



Source link

Leave a Reply

Your email address will not be published. Required fields are marked *