2009-05-28 5 views
3

Я хотел бы изменить размер массива ctypes. Как вы можете видеть, ctypes.resize не работает так, как мог. Я могу написать функцию для изменения размера массива, но я хотел знать некоторые другие решения. Может быть, мне не хватает трюка ctypes или, возможно, я просто использовал изменение размера неправильно. Имя c_long_Array_0, кажется, говорит мне, что это может не работать с изменением размера.Resize ctypes array

>>> 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 

Edit: Может быть, пойти что-то вроде:

>>> 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

Скотт, я забыл одно. Я думаю, если бы ваш массив был инициализирован так, как мы это делаем (без mallocing block, позволяя ctypes делать это), тогда вам нужно сохранить ссылку на исходный объект в новом объекте ctypes, потому что я думаю, что память освобождается, когда первая объект умирает. Поэтому вам нужно будет сделать «if hasattr (array,« original »), newarray.original = array.original, else newarray.original = array». Тогда сборщик мусора будет мусор исходного массива, который, в свою очередь, освобождает блок. Если вам нужна помощь, просто спросите в поле для комментариев. – Unknown

+0

Gotcha. Я столкнулся с проблемой, когда я не мог изменить размер члена _field_ в структуре ctypes. Что-то о том, что память не принадлежит или что-то еще. Не огромная сделка. – Scott

+0

Хорошо, я думаю, что у меня проблема с gc: python: Модули/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

Я думаю, что я один из немногих экспертов ctypes. Странно, что я написал пару привязок c/python и почти не имею опыта с pyrex/boost/regular modules. – Unknown

+0

Позвольте мне спросить вас об этом. Могу ли я использовать указатели ctypes, например, C-указатели? Как перемещение массива символов с добавлением или вычитанием? – Scott