Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add ability to force alignment of ctypes.Structure #112433

Closed
monkeyman192 opened this issue Nov 27, 2023 · 1 comment
Closed

Add ability to force alignment of ctypes.Structure #112433

monkeyman192 opened this issue Nov 27, 2023 · 1 comment
Labels
topic-ctypes type-feature A feature request or enhancement

Comments

@monkeyman192
Copy link
Contributor

monkeyman192 commented Nov 27, 2023

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

@serhiy-storchaka
Copy link
Member

Thank you for your contribution @monkeyman192.

kumaraditya303 added a commit that referenced this issue Oct 8, 2024
Co-authored-by: Kumar Aditya <kumaraditya@python.org>
JelleZijlstra pushed a commit to JelleZijlstra/cpython that referenced this issue Oct 8, 2024
pythonGH-125087)

(cherry picked from commit 5967dd8)

Co-authored-by: monkeyman192 <monkey_man_192@yahoo.com.au>
Co-authored-by: Kumar Aditya <kumaraditya@python.org>
JelleZijlstra added a commit that referenced this issue Oct 8, 2024
…125087) (#125113)

(cherry picked from commit 5967dd8)

Co-authored-by: monkeyman192 <monkey_man_192@yahoo.com.au>
Co-authored-by: Kumar Aditya <kumaraditya@python.org>
efimov-mikhail pushed a commit to efimov-mikhail/cpython that referenced this issue Oct 9, 2024
…on#125087)


Co-authored-by: Kumar Aditya <kumaraditya@python.org>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
topic-ctypes type-feature A feature request or enhancement
Projects
None yet
Development

No branches or pull requests

3 participants