2009-05-28 26 views
3

ctypes配列のサイズを変更したいと思います。ご覧のとおり、ctypes.resizeは可能なように動作しません。私は、配列のサイズを変更する関数を書くことができますが、私はこれに対する他の解決策を知りたかったのです。たぶん私はいくつかのctypesのトリックが欠けているか、多分私は単に間違ったサイズ変更を使用しました。 c_long_Array_0という名前は、これがサイズ変更では機能しないかもしれないと私に伝えているようです。ctypes配列のサイズ変更

>>> from ctypes import * 
>>> c_int * 0 
<class '__main__.c_long_Array_0'> 
>>> intType = c_int * 0 
>>> foo = intType() 
>>> foo 
<__main__.c_long_Array_0 object at 0xb7ed9e84> 
>>> foo[0] 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
IndexError: invalid index 
>>> resize(foo, sizeof(c_int * 1)) 
>>> foo[0] 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
IndexError: invalid index 
>>> foo 
<__main__.c_long_Array_0 object at 0xb7ed9e84> 
>>> sizeof(c_int * 0) 
0 
>>> sizeof(c_int * 1) 
4 

編集:たぶんのようなもので行く:

>>> ctypes_resize = resize 
>>> def resize(arr, type): 
...  tmp = type() 
...  for i in range(len(arr)): 
...   tmp[i] = arr[i] 
...  return tmp 
...  
... 
>>> listType = c_int * 0 
>>> list = listType() 
>>> list = resize(list, c_int * 1) 
>>> list[0] 
0 
>>> 

しかし、それはタイプの代わりに、サイズを渡し醜いです。それはその目的のために働く、それはそれです。

+0

Scott、私は1つのことを忘れました。私はあなたの配列が初期化されていると思います(ブロックをmallocingせずにctypesを実行させると)、新しいctypesオブジェクトの元のオブジェクトへの参照を保持する必要があります。なぜなら、最初のオブジェクトは死ぬ。したがって、 "if hasattr(array、" original ")、newarray.original = array.original、else newarray.original = array"を実行する必要があります。その後、ガベージコレクタは元の配列をゴミ箱に入れ、ブロックを解放します。あなたが助けを必要とする場合は、コメント欄に質問してください。 – Unknown

+0

Gotcha。私はctypes構造体の_field_メンバのサイズを変更できない問題に遭遇しました。何かが所有されていない記憶について何か。大したことではありません。 – Scott

+0

私はgcの問題に取り組んでいると思う:python:Modules/gcmodule.c:241:update_refs:アサーション 'gc-> gc.gc_refs ==(-3) 'が失敗した。 – Scott

答えて

8
from ctypes import * 

list = (c_int*1)() 

def customresize(array, new_size): 
    resize(array, sizeof(array._type_)*new_size) 
    return (array._type_*new_size).from_address(addressof(array)) 

list[0] = 123 
list = customresize(list, 5) 

>>> list[0] 
123 
>>> list[4] 
0 
+0

私は尋ねられてうれしいです。私は答えを期待していませんでした。 :) – Scott

+1

私はここ数少ない専門家の一人だと思います。不思議なことに、私はいくつかのc/pythonバインディングを書いていて、pyrex/boost/regularモジュールの経験はほとんどありません。 – Unknown

+0

私にこれを聞かせてください。私はCポインタのようなctypesポインタを使うことができますか?加算または減算を使って文字列を走査するのと同じですか? – Scott

関連する問題