Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/357.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 分配空间时的附加括号_Python_Pointers_Memory Management_Ctypes - Fatal编程技术网

Python 分配空间时的附加括号

Python 分配空间时的附加括号,python,pointers,memory-management,ctypes,Python,Pointers,Memory Management,Ctypes,我有下面一行代码。我或多或少知道它的功能——为缓冲区数组分配一些内存。我试图研究语法的含义——附加的括号是用来做什么的?第一个括号内的内容看起来不像函数。我看到,如果一个函数嵌入到另一个函数中,则会使用双括号的构造,但看起来仍然不是这样。此外,当删除任何缓冲区变量(好像它只是1)都不会生成1缓冲区数组时,变量本身是必需的,否则在代码的下一部分中应用程序会崩溃 buffers = (ct.POINTER(ct.c_int8*buf_size)*no_ofBuffers)() 有人对这样的构造有更

我有下面一行代码。我或多或少知道它的功能——为缓冲区数组分配一些内存。我试图研究语法的含义——附加的括号是用来做什么的?第一个括号内的内容看起来不像函数。我看到,如果一个函数嵌入到另一个函数中,则会使用双括号的构造,但看起来仍然不是这样。此外,当删除任何缓冲区变量(好像它只是1)都不会生成1缓冲区数组时,变量本身是必需的,否则在代码的下一部分中应用程序会崩溃

buffers = (ct.POINTER(ct.c_int8*buf_size)*no_ofBuffers)()

有人对这样的构造有更多的经验吗?

首先,这里是官方的ctypes文档页面:(您可能想看看数组部分)。

处理复杂表达式时始终适用的规则是:将其分解为更简单的表达式。我将从内部开始(指出所有中间步骤),并在Python控制台中执行此操作(为了清晰起见,还将更改一些变量名):

导入系统 >>>导入ctypes >>>“Python{:s}on{:s}”。格式(sys.version,sys.platform) “win32上的Python 3.5.4(v3.5.4:3f56838,2017年8月8日,02:17:05)[MSC v.1900 64位(AMD64)]” >>> >>>#数字常量的虚拟值 ... >>>内螺纹尺寸=8#替换buf尺寸 >>>外框尺寸=10#更换无缓冲垫 >>> >>>#声明所有中介类型 ... >>>Int8Arr=ctypes.c_int8*内部_ARR_大小#最里面的“()” >>>Int8ArrPtr=ctypes.POINTER(Int8Arr)#POINTER >>>Int8ArrPtrArr=Int8ArrPtr*外部ARR尺寸#最外层“()” >>> >>>#使用人类可读的名称作为最终类型 ... >>>缓冲区=Int8ArrPtrArr >>> >>>缓冲区 >>>类型(缓冲区) >>> >>>#最后只需将新类型实例化为默认构造值(末尾的“()”就是这样做的) ... >>>buffers=buffers()#这是(复杂)表达式的等价项 >>>缓冲区 >>>类型(缓冲区) >>>len(缓冲器) 10 >>> >>>#这与下面这行的功能类似 ... >>>i=ctypes.c_int() >>>我 库隆(0)
谢谢,解释得很好。我发现最令人困惑的运算是类型的乘法和神奇的结果——一个数组。但这可能是python中的一个常见技巧。是的,ctypes类型继承python序列类型行为,例如:
[8]*3
将产生
[8,8]
。顺便说一句:请您将答案标记为解决方案,以便其他人也知道它解决了您的问题?好的,再次感谢您。我忘了,这是我第一次输入stackoverflow。
>>> import sys
>>> import ctypes
>>> "Python {:s} on {:s}".format(sys.version, sys.platform)
'Python 3.5.4 (v3.5.4:3f56838, Aug  8 2017, 02:17:05) [MSC v.1900 64 bit (AMD64)] on win32'
>>>
>>> # Dummy values for numeric constants
...
>>> INNER_ARR_SIZE = 8  # Replacement for buf_size
>>> OUTER_ARR_SIZE = 10  # Replacement for no_ofBuffers
>>>
>>> # Declare all intermediary types
...
>>> Int8Arr = ctypes.c_int8 * INNER_ARR_SIZE  # Innermost "()"
>>> Int8ArrPtr = ctypes.POINTER(Int8Arr)  # Pointer
>>> Int8ArrPtrArr = Int8ArrPtr * OUTER_ARR_SIZE  # Outermost "()"
>>>
>>> # Use a human readable name for our final type
...
>>> Buffers = Int8ArrPtrArr
>>>
>>> Buffers
<class '__main__.LP_c_byte_Array_8_Array_10'>
>>> type(Buffers)
<class '_ctypes.PyCArrayType'>
>>>
>>> # At the end just instantiate the new type (that's what the "()" at the end do) to a default constructed value
...
>>> buffers = Buffers()  # THIS is the equivalent of your (complex) expression
>>> buffers
<__main__.LP_c_byte_Array_8_Array_10 object at 0x00000235F614A9C8>
>>> type(buffers)
<class '__main__.LP_c_byte_Array_8_Array_10'>
>>> len(buffers)
10
>>>
>>> # It's similar to what the line below does
...
>>> i = ctypes.c_int()
>>> i
c_long(0)