使用ctypes修改整数数组

4 投票
1 回答
3092 浏览
提问于 2025-04-15 13:50

目前我正在把我Python代码中的一个性能瓶颈转移到C语言中,以便研究性能的变化。这个代码会运行一个模拟,并通过ctypes把结果反馈给Python。不过,我在让我的数据类型匹配上遇到了问题。

虽然我想解决这个具体的问题,但我也希望能得到一些关于使用ctypes的更一般性的建议,因为相关的文档和流程似乎有点少。

我有以下这个C语言函数:

extern "C" {
    void f( int* array, int arraylen ) {
        for(int i = 0; i < arraylen; i++) {
            array[i] = g() // mutate the value array[i];
        }
    }
}

还有以下这段Python代码:

import ctypes

plib   = ctypes.cdll.LoadLibrary('./mylib.so')
_f = plib.f
_f.restype  = None
_f.argtypes = [ ctypes.POINTER(ctypes.c_int), ctypes.c_int ]
seqlen = 50
buffer = ctypes.c_int * seqlen
_f( buffer, seqlen )

然而,这段代码运行时出现了以下错误信息:

Traceback (most recent call last):
  File "particle.py", line 9, in <module>
    _f( buffer, seqlen )
ctypes.ArgumentError: argument 1: <type 'exceptions.TypeError'>: expected LP_c_int instance instead of _ctypes.ArrayType

1 个回答

4

看起来你想要了解cast函数

cast函数可以用来把一个ctypes实例转换成指向另一种ctypes数据类型的指针。这个函数需要两个参数,第一个是一个ctypes对象,它可以是某种类型的指针,第二个是ctypes指针类型。它会返回第二个参数的一个实例,这个实例指向和第一个参数相同的内存块:

>>> a = (c_byte * 4)()
>>> a
<__main__.c_byte_Array_4 object at 0xb7da2df4>
>>> cast(a, POINTER(c_int))
<ctypes.LP_c_long object at ...>
>>>

撰写回答