Search code examples
cythontypedef

Importing numeric C typedef into Cython automatically


Say you have a config.h" header defining a numeric type with typedef as

//config.h
typedef int32_t DTYPE_t;

or alternatively via a #define clause such as:

//config.h
#define int32_t DTYPE_t

You could manually replicate (e.g. following this question) the data type in cython with ctypedef:

# my_cython_lib.pyx
from libc.stdint cimport int32_t
ctypedef int32_t DTYPE_t

DTYPE_t a = 1

However, in the event of switching DTYPE_t to int64_t, you would have to do so manually. How can you import DTYPE_t (from a C-level #define or typedef) in the Cython space without explicitly declaring the data type/size? I would expect it to be something inside a cdef extern from block, e.g.,

cdef extern from "config.h":
    ctypedef DTYPE_t dtype_t # Error: DTYPE_t not defined

# This definition is outside of the `cdef extern from` block
dtype_t a = 1

Solution

  • If you declare the type in a cdef extern block then it doesn't really matter if the type doesn't match the C type. E.g.:

    cdef extern from "config.h":
        ctypedef int32_t DTYPE_t # should work fine even if DTYPE_t is actually
                                 # int8_t, int16_t, or int64_t
    

    Practically the C code that Cython generates will just use the name of the C type (DTYPE_t) anyway, so all that's really important is that Cython knows it's an integer type.

    Anywhere that Cython needs to know the size of the type (largely for detecting overflows) it works this out in the generated C code anyway, so doesn't need to know itself.

    This is a fairly common way of handling platform depending types in Cython so is nothing to worry about.