2011-01-18 31 views
4

ctypesの構造体に対してoffsetofを実装できないようです。私は FAQ for ctypesを見ましたが、うまく動作しないか、 詳細がわかりません。Pythonのctypesで構造体のoffsetof()を実装する

Python 2.6.4 (r264:75706, Dec 19 2010, 13:04:47) [C] on sunos5 
Type "help", "copyright", "credits" or "license" for more information. 
>>> from ctypes import * 
>>> class Dog(Structure): 
... _fields_ = [('name', c_char_p), ('weight', c_int)] 
... def offsetof(self, field): 
...  return addressof(field) - addressof(self) 
... 
>>> d = Dog('max', 80) 
>>> d.offsetof(d.weight) 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "<stdin>", line 4, in offsetof 
TypeError: invalid type 
>>> d.offsetof(weight) 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
NameError: name 'weight' is not defined 
>>> d.offsetof('weight') 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "<stdin>", line 4, in offsetof 
TypeError: invalid type 

addressof()は、構造体のメンバ(例えばd.weight)上では動作しませんようです。私は試しました pointer()byref()を含む他のもの、しかし運がありません。もちろん

が、私はこれがポインタ、 とにかかわらず、パディングの効果ののサイズに関係なく、すべてのアーキテクチャ上で動作するようにしたいので、単に以前のすべての要素についてはsizeof() を合計する言わないでください。ただし、C コンパイラが追加するすべてのパディングを確実に行うことができない場合は除きます。

アイデア?ありがとう!

答えて

14
class Dog(Structure): 
    _fields_ = [('name', c_char_p), ('weight', c_int)] 

Dog.name.offset 
# 0 
Dog.weight.offset 
# 4 (on my 32-bit system) 

方法にこれを回すのタスクが読者に任されている:)

+0

ですありがとうございます!良い悲しみ、それは簡単でした。私はctypesのためのdocでそれを見つけることができませんが、私はそれを再読します。 – samf

+0

ctypesのドキュメントは多少不完全であるかもしれません。 –

+0

@zhangyoufu:「うまくいかない」、「配列のために」という意味が明確ではありません。これは、配列を含む構造体に適切なオフセットが得られないことを意味しますか?私のために働く:http://ideone.com/IT8iee –

0

トラブルが構造部材は時々普通のPython型として返されることです。 例えば

class Test(Structure): 
    _fields_ = [('f1', c_char), ('f2', c_char * 0)] 

タイプ(テスト()。F1)タイプ(テスト()。F2)はstrの

+0

Test.f1、Test.f2は、を返します。 ofs = 1、size = 0>。 (つまり、c_charおよびc_char_Array)。 – Andris

関連する問題