Using array.array in Python types

I need to associate a Python program with the C library. The specific function that I need to call takes an array and returns double. The following function has the same signature and is easier to understand than mine:

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

My current solution:

 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) 

But I use the array module a lot in my code, and it seemed to me that using them with C code should be more direct, since it is a typed array. So I tried to directly pass the C function to the array, but that didn't work. To make it work, I wrapped the array as follows:

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

where TYPES maps type-type from an array to ctypes types:

  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} 

Is there a way to replace _as_parameter_ with something that doesn't create another array?

thanks

+4
source share
2 answers

use array.buffer_info () to get the address and length, and enter () the address in 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) 
+4
source

Not that this was the best answer, but for completeness, if you use numpy , this is slightly different, since numpy can handle the cast part for you.

 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)) 
0
source

Source: https://habr.com/ru/post/1412885/


All Articles