【问题标题】:ctypes pointer to a c_int vs array of c_intsctypes 指向 c_int 与 c_ints 数组的指针
【发布时间】:2014-09-25 00:18:14
【问题描述】:

我正在尝试调用 dll 中的函数。该函数称为pop(),它接受两个参数,一个int 和一个指向int 的指针。第一个参数是从第二个参数开始的数组的长度。此函数应返回一个指向 int 的指针,该指针是 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) 类型不同,因为我相信这就是我所做的全部更改。但是,the Python documentation 似乎暗示它们应该是相同的。这里发生了什么?具体来说,为什么两个版本的代码执行的不一样?

【问题讨论】:

  • 64 位 Windows 和/或 Python?
  • 64 位 Windows 和 Python
  • 我猜它归结为指针和数组在 C 中实际上并不是相同的东西,即使它们非常相似。
  • 尝试使用c_void_pc_longlong 代替c_int,因为它们在64 位Windows 上应该是指针大小(c_int 仍然是32 位)。
  • @figs c_void_p 和 c_longlong 都给出了不同的和不需要的输出。我还测试了 c_long 和 c_short,它们同样给出了不希望的结果。

标签: python arrays pointers ctypes


【解决方案1】:
>>> platform.architecture()
('64bit', 'WindowsPE')
>>> ctypes.sizeof(ctypes.c_int*4)
16
>>> ctypes.sizeof(ctypes.POINTER(ctypes.c_int))
8

显然,这些是不同的实体。具体来说,数组不能从 C 函数返回,因为它不适合寄存器。

在第二种情况下,您的结果是您返回的int*ctypes 保存在某处并解释为int[4]:第一个是您的指针,还有一些垃圾在以下地址。在 x64 上,第一个是地址的一个 DWORD,下一个是另一个 DWORD(这取决于您的字节序),其余的都是垃圾。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-01-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-03
    • 1970-01-01
    • 2018-10-14
    • 2018-04-05
    相关资源
    最近更新 更多