ctypes指针指向c_int与c_int数组的区别

3
我正在尝试调用dll中的一个函数,该函数名为pop(),有两个参数,一个整数和指向整数的指针。第一个参数是第二个参数开始的数组的长度。此函数应返回指向整数的指针,它是由n-1个元素组成的数组的第一个元素,其中n是原始数组中的元素数量。返回的数组应该是原始数组,不包括第0个元素。

我的代码:

from ctypes import cdll, c_int, POINTER

lib = cdll.LoadLibrary('extlib.dll')

lib.pop.restype = POINTER(c_int)
#lib.pop.restype = c_int*4

testArray = (c_int*5)(*[5,6,7,8,9])
output = list(lib.pop(5, testArray)[0:4])

print output

当按原样运行时,它会产生以下(预期的)输出:
[6, 7, 8, 9]

如果我取消注释下面的代码行,并注释上面的代码行,将会得到(意料之外的)输出结果:
[6618688, 0, 2, 0]

看起来类型 c_int*4POINTER(c_int) 是不同的,我相信这就是我改变的全部内容。然而,Python文档似乎表明它们应该是一样的。这是怎么回事?具体地说,为什么这两个代码版本的执行结果不同?


64位的Windows和/或Python? - 101
64位的Windows和Python。 - Matt
我猜这归结于指针和数组在C语言中并不是同一种东西,即使它们非常相似。 - Matt
尝试使用c_void_pc_longlong代替c_int,因为在64位Windows上它们应该是指针大小(c_int仍然是32位)。 - 101
@figs c_void_p和c_longlong都给出了不同且不期望的输出。我还测试了c_long和c_short,同样得到了不期望的结果。 - Matt
1个回答

3
>>> platform.architecture()
('64bit', 'WindowsPE')
>>> ctypes.sizeof(ctypes.c_int*4)
16
>>> ctypes.sizeof(ctypes.POINTER(ctypes.c_int))
8

显然,这些是不同的实体。具体而言,数组无法从C函数返回,因为它无法适应寄存器。
在第二种情况下,您的结果是由ctypes保存的int*,并将其解释为int[4]:第一个是指针,接下来的一些是以下地址处的垃圾。在x64上,第一个是地址的一个DWORD,下一个是另一个DWORD(哪个取决于您的字节顺序),其余都是垃圾。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接