ctypes 将另一个结构中的结构保存到文件中

Posted

技术标签:

【中文标题】ctypes 将另一个结构中的结构保存到文件中【英文标题】:ctypes save a structure within another structure to a file 【发布时间】:2022-01-13 01:12:59 【问题描述】:

我想用 ctypes 将其他结构中的许多结构保存在一个文件中,但它不起作用,另一个结构中的结构没有保存在文件中。只有“根”结构仍然保存在文件中。

import ctypes


class A(ctypes.Structure):
    _pack_ = 1
    _fields_ = [("x", ctypes.c_char * 15)]

A._fields_.append(("y", A))

with open("test.struct", "wb+") as f:
    root = A(h := b"Hello")
    root.y = A(b"hi")
    f.write(root.y)
    f.write(root)


with open("test.struct", "rb+") as f:
    b = A()
    f.readinto(b)
    z = b
    o = 0
    print(b.x)
    o += 1
    print(o, z.x)
    z = z.y

如何将结构中的结构保存到具有 ctypes 的文件中?

Python:3.10 - Linux

【问题讨论】:

这段代码的结果应该是什么?此外,作为一般规则,结构不能包含自身。 【参考方案1】:

我认为这里的问题是定义不完整的结构。一旦设置了 _fields_ 属性,就不应更改它。更多详情,请查看[Python.Docs]: ctypes - Incomplete Types。 此外,该代码还有另一个缺陷:试图在自身内部定义一个结构。这是不可能的,在这些情况下应该使用指针。

我稍微修改了你的代码。

code00.py

#!/usr/bin/env python

import ctypes as ct
import sys


class A(ct.Structure):
    _pack_ = 1
    _fields_ = [
        ("x", ct.c_char * 15)
    ]

A._fields_.append(("y", A))


class B(ct.Structure):
    _pack_ = 1

B._fields_ = (
    ("x", ct.c_char * 15),
    ("y", A),
)


def main(*argv):
    if len(sys.argv) > 1:
        TestStruct = B
    else:
        TestStruct = A

    file_name = "test.struct"

    with open(file_name, "wb+") as f:
        root = TestStruct(h:=b"Hello")
        root.y = A(b"hi")
        f.write(root)

    with open(file_name, "rb+") as f:
        b = TestStruct()
        f.readinto(b)
        print(b.x)
        print(b.y.x)


if __name__ == "__main__":
    print("Python :s :03dbit on :s\n".format(" ".join(elem.strip() for elem in sys.version.split("\n")),
                                                   64 if sys.maxsize > 0x100000000 else 32, sys.platform))
    rc = main(*sys.argv[1:])
    print("\nDone.")
    sys.exit(rc)

输出

[cfati@CFATI-5510-0:e:\Work\Dev\***\q070269014]> "e:\Work\Dev\VEnvs\py_pc064_03.08.07_test0\Scripts\python.exe" code00.py
Python 3.8.7 (tags/v3.8.7:6503f05, Dec 21 2020, 17:59:51) [MSC v.1928 64 bit (AMD64)] 064bit on win32

b'Hello'
Traceback (most recent call last):
  File "code00.py", line 47, in <module>
    rc = main(*sys.argv[1:])
  File "code00.py", line 41, in main
    print(b.y.x)
AttributeError: 'A' object has no attribute 'y'

[cfati@CFATI-5510-0:e:\Work\Dev\***\q070269014]> "e:\Work\Dev\VEnvs\py_pc064_03.08.07_test0\Scripts\python.exe" code00.py dummy
Python 3.8.7 (tags/v3.8.7:6503f05, Dec 21 2020, 17:59:51) [MSC v.1928 64 bit (AMD64)] 064bit on win32

b'Hello'
b'hi'

Done.

【讨论】:

AttributeError: 'A' object has no attribute 'y' 是的。如果你看,当我在没有参数的情况下运行它时,我得到了同样的错误(这是你的场景的再现)。 @KapesoftFx:如果我想得更好,你的(最后)评论是关于什么的? A > B > A > B 最后一个序列不起作用 ______ 我还是不明白。我发布的代码可以正常工作。 A 不应该工作,因为没有以正确的方式定义。我添加了 B 作为示例。

以上是关于ctypes 将另一个结构中的结构保存到文件中的主要内容,如果未能解决你的问题,请参考以下文章

ctypes给扩展模块中的函数传递数组和结构体

如何管理 ctypes 中的嵌套结构?

在 Python/ctypes 中的结构内取消引用 C 函数指针

C ++将结构中的字符串保存到文本文件中

复杂 Ctypes 结构的问题

使用 ctypes 传递结构指针