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

すべてが正常に機能します。ここで、id0xAAAAAAAAになり、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_copyctypes._CData方法であることを発見しました。ドキュメントでは、その_CDataクラスは非公開クラスであると読むことができます。

だからここに私の問題。コンストラクターで使用したいfrom_buffer_copyのですが、現時点では「呼び出し不可」に見えます。私たちを手伝ってくれますか ?

お返事ありがとうございますよろしく

PS:実際のコードでは、 fields変数super(MyStruct,self).__init__(id=0x44444444,perm=0x11111111)に多くの引数があるため、このスタイルは使用したくありません。

4

1 に答える 1

10

問題は、from_buffer_copy が指定されたバッファーから新しいStructure インスタンスを作成することです。__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 に答える