2011-02-10 21 views
9

Dostaję następujący komunikat ostrzegawczy, gdy próbuję użyć tablicę ctypes jako numpy tablicy:PEP 3118 ostrzegawczy przy użyciu ctypes tablicę jako numpy tablicy

Python 2.7.1 (r271:86832, Nov 27 2010, 18:30:46) [MSC v.1500 32 bit (Intel)] on 
win32 
Type "help", "copyright", "credits" or "license" for more information. 
>>> import ctypes, numpy 
>>> TenByteBuffer = ctypes.c_ubyte * 10 
>>> a = TenByteBuffer() 
>>> b = numpy.ctypeslib.as_array(a) 
C:\Python27\lib\site-packages\numpy\ctypeslib.py:402: RuntimeWarning: Item size 
computed from the PEP 3118 buffer format string does not match the actual item s 
ize. 
    return array(obj, copy=False) 
>>> b 
array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0], dtype=uint8) 

Kod wydaje się działać, choć. Czy ignorowanie tego ostrzeżenia jest złym pomysłem?

Tło: Dzwonię do biblioteki DLL, która generuje dane w czasie rzeczywistym. Muszę przekazać DLL szereg buforów do przechowywania danych. Czekając na wypełnienie następnego bufora, chciałbym przetworzyć najnowszy bufor z numpy i zapisać wynik. Generuję bufory z kodem jak powyżej i rzeczy wydają się działać, ale nie chcę zamiatać ważnego problemu pod dywan.

+1

Co ciekawe, wydaje się, że nie dzieje się to z python2.6, tylko python2.7 ... –

Odpowiedz

10

To błąd w Pythonie. ctypes obecnie wytwarza nieprawidłowe PPG 3118 kodami, które NumPy UWAGI: http://bugs.python.org/issue10746 http://bugs.python.org/issue10744

Gdy taka niezgodność występuje, Numpy pomija pomocą interfejsu bufora PPG 3118 i wraca do życia (przestarzałe) interfejsu buforowego. To powinno działać poprawnie.

Możesz wyciszyć ostrzeżenie za pomocą modułu Pythona warnings. Jednak ostrzeżenie może mieć wpływ na wydajność.

Możesz również spróbować obejść problem przez zawijanie obiektu ctypes w buffer().

+0

Doskonale, dziękuję. Cieszę się, że to znany błąd, a nie ja robię coś głupiego. – Andrew

+0

Czy ktokolwiek może komentować jakąkolwiek zmianę wydajności przez zawijanie obiektów ctypes za pomocą ['buffer()'] (http://docs.python.org/2/library/functions.html#buffer)? Czy ta metoda działa niezawodnie? Jak to się różni od tworzenia nowej tablicy numpy z tablicy ctype EG: 'np.array (my_ctype_array [:]) .reformacja ([z powrotem, do, oryginału])' inny dziękuję kształtowanie kształtu? Myślałem, że 'ctypeslib.as_array()' jest zalecaną praktyką, ale komunikat ostrzegawczy jest naprawdę denerwujący i wyłączy użytkowników nietechnicznych. Dzięki. –

+1

Zawijanie obiektów ctypes za pomocą ['buffer()'] (http://docs.python.org/2/library/functions.html#buffer) nie ** działa ** dla mnie EG: 'new = numpy. ctypeslib.as_array (buffer (old)) 'zwraca *** TypeError: buffer() przyjmuje co najmniej 1 argument (0 podany) ***. Czy ktokolwiek może dodać więcej klarowności do opcji 'wrap()' wrap? Dzięki! –

3

Jest bardziej wygodny sposób robienia tego, który unika ostrzeżenie sumie:

Zamiast tworzyć dane jako tablicę ctypes, a następnie przekształcenie go do tablicy numpy, wystarczy utworzyć go jako tablicy numpy od razu, a następnie użyj numpy.ctypeslib.ndpointer jako specyfikatora typu w swoim prototypie ctypes. Jako przykład, powiedzmy, że masz funkcję C o nazwie f która przyjmuje char* i size_t jako argumenty

void f(char* buf, size_t len); 

Twój prototyp ctypes będzie

from numpy.ctypeslib import ndpointer 
some_dll = ctypes.CDLL(...) 
some_dll.f.argtypes = [ndpointer(numpy.uint8, flags="C_CONTIGUOUS"), 
         ctypes.c_size_t] 
some_dll.f.restype = None 

i można wywołać tę funkcję jako

+0

Bardzo ładne! Nie używałem wcześniej argtypów, spróbuję tego. – Andrew

Powiązane problemy