Skip to content

Add ability to force alignment of ctypes.Structure #112433

Closed
@monkeyman192

Description

@monkeyman192

Feature or enhancement

Proposal:

When creating a ctypes.Structure to map data from c/c++ to python, I have been coming up against issues where I have a structure which has an alignment due to a #pragma align.
Currently there is no way to define a ctypes.Structure which can map to an object like this.

I propose we add an _align_ attribute to the ctypes.Structure class which will instruct the code how to align the structure itself in memory.
In the way that the _pack_ attribute indicates the maximum alignment of the fields in the struct, this would indicate the minimum alignment of the struct itself.

An example of such a struct and it's use is as follows:

import ctypes

class IDString(ctypes.Structure):
    _align_ = 0x10
    _fields_ = [
        ("string", ctypes.c_char * 0x10),
    ]

class main(ctypes.Structure):
    _fields_ = [
        ("first", ctypes.c_uint32),
        ("second", ctypes.c_ubyte),
        ("string", IDString),
    ]

data = bytearray(
    b"\x07\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
    b"\x68\x65\x6c\x6c\x6f\x20\x77\x6f\x72\x6c\x64\x21\x00\x00\x00\x00"
)
m = main.from_buffer(data)
print(f"first: {m.first}")  # first: 7
print(f"second: {m.second}")  # second: 1
print(f"string: {m.string.string}")  # string: b'hello world!'

Without the _align_ attribute the value of m.string.string would just be an empty bytes object since it would be reading from 8 bytes into the bytearray.

I have already made a (preliminary) implementation of this here.

Because the attribute is optional, I believe there are no potential backward compatibility issues as the default alignment will simply be what it was before (ie. 1).

Has this already been discussed elsewhere?

I have already discussed this feature proposal on Discourse

Links to previous discussion of this feature:

https://discuss.python.org/t/add-ability-to-force-alignment-of-ctypes-structure/39109

Linked PRs

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions