3

我有以下代码:

class MyStruct(ctypes.Structure):
      _fields_= [('id', ctypes.uint),
                 ('perm', ctypes.uint)]

定义类后,我可以直接在我的字段上从缓冲区复制数据。例如:

ms = MyStruct.from_buffer_copy("\xAA\xAA\xAA\xAA\x11\x11\x11\x11")
print ms.id, ms.perm

一切正常,这里id将是0xAAAAAAA并且perm等于0x11111111

现在,我尝试在实例化过程中做同样的事情,使用以下代码:

class MyStruct(ctypes.Structure):
      _fields_= [('id', ctypes.uint),
                 ('perm', ctypes.uint)]
      def __init__(self):
          super(MyStruct, self).__init__()
          self.from_buffer_copy("\xAA\xAA\xAA\xAA\x11\x11\x11\x11")

ms = MyStruct()
print ms.id, ms.perm

但是我的代码使用以下语句引发错误:

AttributeError:“MyStruct”对象没有属性“from_buffer_copy”

经过一番研究,我发现这from_buffer_copy是一种ctypes._CData方法。在文档中,我们可以读到_CData该类是非公共类

所以这是我的问题。我想from_buffer_copy在构造函数中使用,但此时它看起来“不可调用”。你可以帮帮我吗 ?

提前感谢您的回复问候

PS:我不想使用这种风格,因为在我的真实代码中,我的fieldssuper(MyStruct,self).__init__(id=0x44444444,perm=0x11111111)变量上有很多参数。

4

1 回答 1

10

问题是 from_buffer_copy 从给定的缓冲区创建的结构实例。当你在 __init__ 中使用它时,结构已经被创建,因此无法使用 from_buffer_copy (这就是为什么它只能作为类方法使用,而不是实例方法)。

一个简单的解决方案是继续使用 MyStruct.from_buffer_copy 或编写另一个工厂函数以满足您的需求。如果你坚持使用 MyStruct(buffer),那么你可以使用 __new__ 来达到这个目的,因为它在实例创建之前被调用:

import ctypes
class MyStruct(ctypes.Structure):
    _fields_= [('id', ctypes.c_uint),('perm', ctypes.c_uint)]
    def __new__(cls, buf):
        return cls.from_buffer_copy(buf)

    def __init__(self, data):
        pass  ## data is already present in class

ms = MyStruct("\xAA\xAA\xAA\xAA\x11\x11\x11\x11")
print ms.id, ms.perm
于 2012-07-14T17:56:59.393 回答