Issue 10746: ctypes c_long & c_bool have incorrect PEP-3118 type codes (original) (raw)

Currently on Python 3.x:

import ctypes memoryview(ctypes.c_long()).format '<l'

This is invalid on 64-bit platforms: the above means 32-bit little-endian float. The '<' endian specification turns on the "standard size" mode (similarly as for the struct module), which makes type character have a platform-independent meaning.

Unfortunately, the struct module format syntax does not allow specifying native-size non-native-endian items. So just replacing '<' by '^' cannot be in general be done.

Suggested fix attached. It adds a converter function that maps the platform-dependent ctypes codes to struct module standard-size codes; handling c_long and c_bool specially.

***

After this patch (and the one in http://bugs.python.org/issue10744 ):

import numpy as np from ctypes import * class Point(Structure): ... fields = [("x", c_long), ("y", c_long)] ... class StructWithArrays(Structure): ... fields = [("x", c_long * 3 * 2), ("y", Point * 4)] ... x = StructWithArrays() y = np.asarray(x) y.dtype dtype([('x', '<i8', (2, 3)), ('y', [('x', '<i8'), ('y', '<i8')], (4,))]) y['x'] = [[1,2,3],[4,5,6]] y['y']['x'] = np.arange(4) + 10 y['y']['y'] = np.arange(4) + 20 x.x[0][0] 1 x.x[0][1] 2 x.x[0][2] 3 x.y[0].x 10 x.y[1].x 11 x.y[0].y 20 x.y[1].y 21