当使用ctypes数组作为numpy数组时,PEP 3118会发出警告

And*_*rew 12 python warnings ctypes numpy pep3118

当我尝试将ctypes数组用作numpy数组时,我收到以下警告消息:

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)
Run Code Online (Sandbox Code Playgroud)

但是代码似乎正在起作用.忽略这个警告是不是一个坏主意?

背景:我正在调用一个实时生成数据的C DLL.我需要传递DLL一系列缓冲区来保存数据.在等待下一个缓冲区填充时,我想用numpy处理最新的缓冲区并保存结果.我正在使用上面的代码生成缓冲区,但似乎工作正常,但我不想在地毯下扫描一个重要的问题.

pv.*_*pv. 12

这是Python中的一个错误.ctypes目前生成无效的PEP 3118类型代码,Numpy注意到:http : //bugs.python.org/issue10746 http://bugs.python.org/issue10744

当出现这种不一致时,Numpy会跳过使用PEP 3118缓冲区接口,并回退到旧的(过时的)缓冲区接口.这应该正常工作.

您可以使用Python的warnings模块使警告静音.但是,警告可能会对性能产生影响.

您还可以尝试通过包装ctypes对象来解决此问题buffer().

  • 用 [`buffer()`](http://docs.python.org/2/library/functions.html#buffer) 包装 ctypes 对象对我来说**不起作用** EG:`new = numpy.ctypeslib .as_array(buffer(old))` 返回***类型错误:buffer() 至少需要 1 个参数(给定 0 个)***。任何人都可以为 `buffer()` 换行选项添加更多清晰度吗?谢谢! (2认同)

Sve*_*ach 5

有一种更方便的方法,可以完全避免警告:

与其先将数据创建为ctypes数组然后再将其转换为NumPy数组,不如立即将其创建为NumPy数组,然后numpy.ctypeslib.ndpointer在ctypes原型中用作类型说明符。举例来说,假设您有一个名为C的函数f,该函数以a char*和a size_t作为参数:

void f(char* buf, size_t len);
Run Code Online (Sandbox Code Playgroud)

您的ctypes原型将是

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
Run Code Online (Sandbox Code Playgroud)

您可以将该函数称为

a = numpy.zeros(10, numpy.uint8)
f(a, a.size)
Run Code Online (Sandbox Code Playgroud)