[issue22781] ctypes: Differing results between Python and C.
eryksun
report at bugs.python.org
Sat Nov 1 23:38:16 CET 2014
eryksun added the comment:
ctypes doesn't always handle bitfields correctly. In particular it doesn't adapt the storage unit size when packed. A bitfield based on c_uint is always stored in 4 bytes, even if _pack_ is set to 1. This is MSVC rules, so all is well on Windows.
For example, from ifo_types.h:
typedef struct {
unsigned int zero_1 : 1;
unsigned int multi_or_random_pgc_title : 1; /* 0: one sequential pgc title */
unsigned int jlc_exists_in_cell_cmd : 1;
unsigned int jlc_exists_in_prepost_cmd : 1;
unsigned int jlc_exists_in_button_cmd : 1;
unsigned int jlc_exists_in_tt_dom : 1;
unsigned int chapter_search_or_play : 1; /* UOP 1 */
unsigned int title_or_time_play : 1; /* UOP 0 */
} ATTRIBUTE_PACKED playback_type_t;
ctypeslib translates this as follows:
class playback_type_t(Structure):
pass
playback_type_t._fields_ = [
('zero_1', c_uint, 1),
('multi_or_random_pgc_title', c_uint, 1),
('jlc_exists_in_cell_cmd', c_uint, 1),
('jlc_exists_in_prepost_cmd', c_uint, 1),
('jlc_exists_in_button_cmd', c_uint, 1),
('jlc_exists_in_tt_dom', c_uint, 1),
('chapter_search_or_play', c_uint, 1),
('title_or_time_play', c_uint, 1),
]
It doesn't set _pack_ = 1, but ctypes wouldn't use that to pack the c_uint bitfield anyway. It's 4 bytes, either way. MSVC agrees, even with #pragma pack(1). OTOH, with __attribute__((packed)), gcc packs the bitfield into a single byte.
The incorrect packing (for gcc) of playback_type_t results in an incorrect offset for title_set_nr in title_info_t:
class title_info_t(Structure):
pass
title_info_t._pack_ = 1
title_info_t._fields_ = [
('pb_ty', playback_type_t),
('nr_of_angles', uint8_t),
('nr_of_ptts', uint16_t),
('parental_id', uint16_t),
('title_set_nr', uint8_t),
('vts_ttn', uint8_t),
('title_set_sector', uint32_t),
]
As a workaround for the immediate problem, on platforms that use gcc you can use c_uint8 in playback_type_t instead of c_uint. You'll want to verify other bitfields as well. I don't know about other compilers on other platforms.
Working at the ABI level can be painful. Consider using CFFI's API level interface instead:
https://cffi.readthedocs.org
----------
nosy: +eryksun
_______________________________________
Python tracker <report at bugs.python.org>
<http://bugs.python.org/issue22781>
_______________________________________
More information about the Python-bugs-list
mailing list