Python ctypes 结构体数组

13

我有以下代码,但最终导致分段错误。

import ctypes
from random import randint

class STRUCT_2(ctypes.Structure):
    #_pack_=2
    _fields_ = [('field_1', ctypes.c_short),
                ('field_2', ctypes.c_short),
                ('field_3', ctypes.c_short)]

class STRUCT_1(ctypes.Structure):
    #_pack_=2
    _fields_ = [('elements', ctypes.c_short),
                ('STRUCT_ARRAY', ctypes.POINTER(STRUCT_2))]

    def __init__(self,num_of_structs):
        elems = (ctypes.POINTER(STRUCT_2) * num_of_structs)()
        self.STRUCT_ARRAY = ctypes.cast(elems,ctypes.POINTER(STRUCT_2))
        self.elements = num_of_structs

        for num in range(0,num_of_structs):
            self.STRUCT_ARRAY[num].field_1 = 1
            self.STRUCT_ARRAY[num].field_2 = 2
            self.STRUCT_ARRAY[num].field_3 = 3

for num in range(0,100):
    test = STRUCT_1(num)
    print "%i done" % num

输出: 5 完成 分段错误

但是如果在 struct_2 中没有 field_3,那么它似乎可以正常工作。如果我再添加一个短字段(field_4),它就会出现分段错误...

那么我做错了什么或者我在这里错过了什么?

有没有其他定义数组大小的方法?


为什么不直接执行 self.STRUCT_ARRAY.append({"field_1": 1, "field_2": 2, "field_3": 3}) - mishik
1个回答

20

您的代码中的STRUCT_ARRAY应该是指向指针数组的指针,而不是指向数组中元素的指针,因为您正在将STRUCT_2指针附加到数组中。

在C语言中,STRUCT_ARRAY可以定义为*STRUCT_2[length],也就是STRUCT_2指针的数组。

import ctypes
from random import randint

class STRUCT_2(ctypes.Structure):
    #_pack_=2
    _fields_ = [('field_1', ctypes.c_short),
                ('field_2', ctypes.c_short),
                ('field_3', ctypes.c_short),
                ('field_4', ctypes.c_short),
                ('field_5', ctypes.c_short),
                ('field_6', ctypes.c_short),
                ('field_7', ctypes.c_short),
                ('field_8', ctypes.c_short)]

class STRUCT_1(ctypes.Structure):
    #_pack_=2
    _fields_ = [('elements', ctypes.c_short),
                #an array of pointers
                ('STRUCT_ARRAY', ctypes.POINTER(ctypes.POINTER(STRUCT_2)))]

    def __init__(self,num_of_structs):
        elems = (ctypes.POINTER(STRUCT_2) * num_of_structs)()
        self.STRUCT_ARRAY = ctypes.cast(elems,ctypes.POINTER(ctypes.POINTER(STRUCT_2)))
        self.elements = num_of_structs

        for num in range(0,num_of_structs):
            self.STRUCT_ARRAY[num].field_1 = 1
            self.STRUCT_ARRAY[num].field_2 = 2
            self.STRUCT_ARRAY[num].field_3 = 3

for num in range(0,100):
    test = STRUCT_1(num)
    print("%i done" % num)

如果您想要的是一个结构体数组,使用以下代码:

import ctypes
from random import randint

class STRUCT_2(ctypes.Structure):
    #_pack_=2
    _fields_ = [('field_1', ctypes.c_short),
                ('field_2', ctypes.c_short),
                ('field_3', ctypes.c_short),
                ('field_4', ctypes.c_short),
                ('field_5', ctypes.c_short),
                ('field_6', ctypes.c_short),
                ('field_7', ctypes.c_short),
                ('field_8', ctypes.c_short)]

class STRUCT_1(ctypes.Structure):
    #_pack_=2
    _fields_ = [('elements', ctypes.c_short),
                #an array of structs
                ('STRUCT_ARRAY', ctypes.POINTER(STRUCT_2))]

    def __init__(self,num_of_structs):
        elems = (STRUCT_2 * num_of_structs)()
        self.STRUCT_ARRAY = ctypes.cast(elems,ctypes.POINTER(STRUCT_2))
        self.elements = num_of_structs

        for num in range(0,num_of_structs):
            self.STRUCT_ARRAY[num].field_1 = 1
            self.STRUCT_ARRAY[num].field_2 = 2
            self.STRUCT_ARRAY[num].field_3 = 3
            self.STRUCT_ARRAY[num].field_4 = 4

for num in range(0,100):
    test = STRUCT_1(num)
    print("%i done" % num)

如果我想通过udp在上面的代码中传递self.STRUCT_ARRAY,你能告诉我怎么做吗?还有一个问题存在于上述代码中,如果我尝试打印field_1、field_2、field_3变量的值,它会显示错误,例如AttributeError: 'LP_STRUCT_2'对象没有属性'field_1'。 - Anurag Singh

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接