LoginSignup
0
0

More than 1 year has passed since last update.

【小ネタ】ctypes.Structureを使う際のアラインメント

Last updated at Posted at 2022-10-26

PythonでバイナリファイルとI/Oしたいとき「ctypes.Structure」を使用するのだが、アラインメントの調整が入るのが気に入らなかった。
ドキュメントをちゃんと見たら調整方法が書いてあったので、忘備録としてメモ。
https://docs.python.org/ja/3/library/ctypes.html#structure-union-alignment-and-byte-order

普通の使い方

こんな感じで使用します。

import ctypes
class Test1(ctypes.Structure):
    _fields_ = [
        ("X", ctypes.c_int32),
        ("Y", ctypes.c_int32),
        ("Z", ctypes.c_int32),
    ]

この場合のサイズは12バイトです。

test1 = Test1()
ctypes.sizeof(test1)

12

アラインメントで調整されてしまう書き方

これだと、アラインメントでサイズが変更されます。

class Test2(ctypes.Structure):
    _fields_ = [
        ("X", ctypes.c_int32),
        ("a", ctypes.c_int64),
    ]

この場合のサイズは16バイトです。

test2 = Test2()
ctypes.sizeof(test2)

16

なお追加される4バイトは、Xとaの間ではなく、最後に追加されるようです。(謎)

対応方法

_pack_でバイトオーダーの値を設定します。
※_fields_より前に設定すること

class Test3(ctypes.Structure):
    _pack_ = 1
    _fields_ = [
        ("X", ctypes.c_int32),
        ("a", ctypes.c_int64),
    ]

※「_pack_ = 4」でもOK
これだとサイズはちゃんと12バイトになります。

test3 = Test3()
ctypes.sizeof(test3)

12
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0