繁体   English   中英

在Python ctypes中使用array.array

[英]Using array.array in Python ctypes

我必须将Python程序与C库连接。 我需要调用的特定函数接受一个数组并返回一个double。 以下函数具有相同的签名,比我自己的更容易理解:

double sum(double * array, const int length) {
 double total = 0;
 int i;
 for (i=0; i<length; i++) {
     total += array[i];
 }
 return total;
}

我目前的解决方案是:

import ctypes
lib = ctypes.CDLL(library_name) 

l = 10
arr = tuple(range(l))

lib.sum.restype = ctypes.c_double
values = (ctypes.c_double * l)(*arr)
ret = lib.sum(values, l)

但是我在我的代码中使用了很多数组模块,在我看来,使用它们与C代码应该更直接,因为它是一个类型化的数组。 所以我尝试直接用数组提供C函数,但它不起作用。 为了使它工作,我像这样包装数组:

class Array(array):

   @property
   def _as_parameter_(self):
      return (TYPES[self.typecode] * len(self))(*self)

其中TYPES将typecode从数组映射到ctypes类型:

   TYPES = {'c': ctypes.c_char,
            'b': ctypes.c_byte,
            'B': ctypes.c_ubyte,
            '?': ctypes.c_bool,
            'h': ctypes.c_short,
            'H': ctypes.c_ushort,
            'i': ctypes.c_int,
            'I': ctypes.c_uint,
            'l': ctypes.c_long,
            'L': ctypes.c_ulong,
            'q': ctypes.c_longlong,
            'Q': ctypes.c_ulonglong,
            'f': ctypes.c_float,
            'd': ctypes.c_double}

有没有办法用不创建另一个数组的东西替换_as_parameter_?

谢谢

使用array.buffer_info()获取地址和长度,并将地址cast()传递给POINTER(c_double):

from array import array
buf = array("d", range(101))
addr, count = buf.buffer_info()
print lib.sum(cast(addr, POINTER(c_double)), count)

并不是说这是一个更好的答案,但为了完整性,如果你使用numpy它只是有点不同,因为numpy可以为你处理演员。

import numpy as np
data = np.arange(101, dtype=ctypes.c_double) # making this match seems important sometimes
print lib.sum(data.ctypes.data_as(ctypes.POINTER(ctypes.c_double)), len(data))

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM