Message230469
Thank you eryksun for the explanation. It's much appreciated. I'll take a
look at CFFI.
On 1 Nov 2014 22:38, "eryksun" <report@bugs.python.org> wrote:
>
> 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@bugs.python.org>
> <http://bugs.python.org/issue22781>
> _______________________________________
> |
|
Date |
User |
Action |
Args |
2014-11-01 22:49:08 | Geoff.Clements | set | recipients:
+ Geoff.Clements, pitrou, meador.inge, eryksun |
2014-11-01 22:49:08 | Geoff.Clements | link | issue22781 messages |
2014-11-01 22:49:08 | Geoff.Clements | create | |
|