简体   繁体   English

Ctypes:获取指向结构字段的指针

[英]Ctypes: Get a pointer to a struct field

I need to get a pointer with the address of a struct field. 我需要获得一个带有结构域地址的指针。 Important: I'm builduing a serializer for a set of c structs so i want to iterate over the fields of a struct and get the address of each of them as a pointer. 重要:我正在为一组c结构构建一个序列化程序,因此我想遍历一个结构的字段并获取它们每个的地址作为指针。 I know there is a way using fields object and offset property of them which is giving you the offset from the address of the structure itself but it is a generic pointer. 我知道有一种使用fields对象和offset属性的方法,该方法可以为您提供与结构本身地址的偏移量,但这是一个通用指针。 Could you show me a way on how to iterate over struct fields and for each of them get a ctypes pointer with a correct inner type? 您能否向我展示一种如何遍历struct字段的方法,并且为每个字段获取一个带有正确内部类型的ctypes指针?

Here's a way... 这是一种方法

The class variable Test._fields_ defines the attributes and their C types. 类变量Test._fields_定义属性及其C类型。 The class attributes generated by assigning the fields contain information about the offset for that attribute, for example: 通过分配字段生成的类属性包含有关该属性的偏移量的信息,例如:

>>> Test.a
<Field type=c_long, ofs=0, size=4>
>>> Test.b
<Field type=c_double, ofs=8, size=8>
>>> Test.c
<Field type=c_char_Array_10, ofs=16, size=10>

For each type, the from_buffer() method builds a C type using the same data buffer as an existing type. 对于每种类型, from_buffer()方法使用与现有类型相同的数据缓冲区来构建C类型。 An instance of the structure implements the buffer API required to access its data, so if you know the offset of a structure element's data, you can generate a ctypes type that references the same data, and create a pointer to it. 结构的实例实现了访问其数据所需的缓冲区API,因此,如果您知道结构元素数据的偏移量,则可以生成引用相同数据的ctypes类型,并创建指向该数据的指针。

from ctypes import *

class Test(Structure):
    _fields_ = [('a',c_int),
                ('b',c_double),
                ('c',c_char * 10)]

x = Test(1,2.5,b'abc')

for field,ftype in Test._fields_:

    # Look up each attribute in the class, and get its offset.
    ofs = getattr(Test,field).offset

    # Create a pointer to the same field type using the same data.
    p = pointer(ftype.from_buffer(x,ofs))
    print(p,p.contents)

Output: 输出:

<__main__.LP_c_long object at 0x000001932DE0EEC8> c_long(1)
<__main__.LP_c_double object at 0x000001932DE0ECC8> c_double(2.5)
<__main__.LP_c_char_Array_10 object at 0x000001932DE0EDC8> <__main__.c_char_Array_10 object at 0x000001932DE0ECC8>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM