Python和C互操作:动态调整CType的大小

Python和C互操作:动态调整CType的大小,python,pointers,ctypes,resize,Python,Pointers,Ctypes,Resize,我试图在Python中与C进行互操作,我有以下函数原型: int testout(unsigned char *test, int *size) 无符号字符的大小由size参数决定。因此,我需要一种在Python中动态调整缓冲区大小的方法,以适应函数调用返回的大小。这对我来说很难理解 从: 这很好,但是如何访问此数组中包含的其他元素呢?由于类型仍然只知道4个元素,因此访问其他元素时会出现错误: >>> short_array[:] [0, 0, 0, 0] >>&

我试图在Python中与C进行互操作,我有以下函数原型:

int testout(unsigned char *test, int *size)
无符号字符的大小由size参数决定。因此,我需要一种在Python中动态调整缓冲区大小的方法,以适应函数调用返回的大小。这对我来说很难理解

从:

这很好,但是如何访问此数组中包含的其他元素呢?由于类型仍然只知道4个元素,因此访问其他元素时会出现错误:

>>> short_array[:]
[0, 0, 0, 0]
>>> short_array[7]
Traceback (most recent call last):
...
IndexError: invalid index
>>>
将可变大小的数据类型与ctypes一起使用的另一种方法是使用Python的动态特性,在已知所需大小后,根据具体情况重新定义数据类型

太好了!我得到indexer错误:无效索引,如示例所示。他们决定不展示如何正确地做到这一点!:

有人知道如何正确调整ctype的大小吗

下面是我的示例代码,除了调整大小之外:

from ctypes import *

lib = "test.so"
dll = cdll.LoadLibrary(lib)
print "Testing pointer output"
dll.testout.argtypes = [POINTER(c_ubyte), POINTER(c_int)]
sizeout = c_int(0)
mem = (c_ubyte * 20)() 
dll.testout(mem, byref(sizeout))
print "Sizeout = " + str(sizeout.value)
for i in range(0,sizeout.value):
    print "Item " + str(i) + " = " + str(mem[i])

如果您从C接收到一个指针,您可以像C指针一样索引相应的ctypes指针


如果需要在Python中分配数组,可以动态创建大小合适的ctypes数组类型。

如果从C接收指针,可以像C指针一样索引相应的ctypes指针


如果需要在Python中分配数组,可以动态创建大小合适的ctypes数组类型。

下面是我们讨论的示例。此代码要求调用方分配缓冲区

测试代码窗口 输出
这是我们讨论的一个例子。此代码要求调用方分配缓冲区

测试代码窗口 输出
Janne,你介意修改一下代码来表达你的意思吗。这是我的“工作代码”。除了数组的动态调整外,一切都正常。Janne,你介意修改这段代码来说明你的意思吗。这是我的“工作代码”。一切正常,但数组的动态大小调整。不确定您想要什么。您的代码在与上一个问题的源代码一起使用时可以工作,但如果您将缓冲区传递到函数中,则应该告诉函数缓冲区有多大:sizeout=c_out20。你发布的是给你一个错误的确切代码吗?马克,这个代码确实有效。但只有在大小为的情况下,因为您的函数不接受无符号字符**,所以它不能返回它为自己分配的任意大小的缓冲区。您的函数正在传递一个已知大小的缓冲区,并且也应该传递大小,大小为c_int20。然后被调用的函数可以检查缓冲区是否足够大以容纳结果,并用使用的数量更新大小。谢谢标记。C、 指针不是我的强项。所以我在函数中处理这个的方式很好。谢谢。你也可以说size=xxxxx和mem=c_ubyte*size来分配不同大小的缓冲区。不确定你想要什么。您的代码在与上一个问题的源代码一起使用时可以工作,但如果您将缓冲区传递到函数中,则应该告诉函数缓冲区有多大:sizeout=c_out20。你发布的是给你一个错误的确切代码吗?马克,这个代码确实有效。但只有在大小为的情况下,因为您的函数不接受无符号字符**,所以它不能返回它为自己分配的任意大小的缓冲区。您的函数正在传递一个已知大小的缓冲区,并且也应该传递大小,大小为c_int20。然后被调用的函数可以检查缓冲区是否足够大以容纳结果,并用使用的数量更新大小。谢谢标记。C、 指针不是我的强项。所以我在函数中处理这个的方式很好。谢谢。您也可以说size=xxxxx和mem=c_ubyte*size来分配不同大小的缓冲区。
// IN: test=pre-allocated buffer.
// IN: size=size of pre-allocated buffer.
// RETURNS: 0 and size set to required size.
//          1 and size set to size used.
__declspec(dllexport) int testout(void *pdata, int *psize)
{
    unsigned char * p = (unsigned char *)pdata;

    if (*psize < 5)
    {
        *psize = 5; // set size required
        return 0;  // fail
    }

    p[0] = 123;
    p[1] = 255;
    p[2] = 237;
    p[3] = 12;
    p[4] = 222;
    *psize = 5; // indicate size used

    return 1;  // pass
}
from ctypes import *

test = CDLL('test')
size = c_int(0)
test.testout.argtypes=[c_void_p,POINTER(c_int)]
print "Result of NULL pointer and zero size:",test.testout(None,byref(size))
print "Returned size:",size.value
mem = (c_ubyte * 2)()
size = c_int(sizeof(mem))
print "sizeof(mem):",size.value
print "Result of small buffer:",test.testout(byref(mem),byref(size))
print "Returned size:",size.value
mem = (c_ubyte * size.value)()
print "Result of exact size buffer:",test.testout(byref(mem),byref(size))
print "Returned size:",size.value
for i in range(size.value):
    print mem[i]
mem = (c_ubyte * 20)()
size = c_int(20)
print "Result of bigger buffer:",test.testout(byref(mem),byref(size))
print "Returned size:",size.value
for i in range(size.value):
    print mem[i]
Result of NULL pointer and zero size: 0
Returned size: 5
sizeof(mem): 2
Result of small buffer: 0
Returned size: 5
Result of exact size buffer: 1
Returned size: 5
123
255
237
12
222
Result of bigger buffer: 1
Returned size: 5
123
255
237
12
222