python - List of Structure subclass returns wrong values when casting to numpy array -
i've built simple structure subclass 2 fields, holding void pointer array, , array length. however, when try create list of these using input lists of same length, value of returned void pointer same last array used create instance:
from ctypes import pointer, c_double, c_size_t, c_void_p, structure, cast import numpy np class external(structure): _fields_ = [("data", c_void_p), ("length", c_size_t)] @classmethod def from_param(cls, seq): return seq if isinstance(seq, cls) else cls(seq) def __init__(self, seq): self.ptr = cast( np.array(seq, dtype=np.float64).ctypes.data_as(pointer(c_double)), c_void_p ) self.data = self.ptr self.length = len(seq) # recreate array void pointer # shows correct values shape = self.length, 2 ptr = cast(self.data, pointer(c_double)) array = np.ctypeslib.as_array(ptr, shape) print "correct array", array.tolist() if __name__ == "__main__": interiors = [ [[3.5, 3.5], [4.4, 2.0], [2.6, 2.0], [3.5, 3.5]], [[4.0, 3.0], [4.0, 3.2], [4.5, 3.2], [4.0, 3.0]], ] wrong = [external(s) s in interiors] w in wrong: # perform same cast array before shape = w.length, 2 ptr = cast(w.data, pointer(c_double)) array = np.ctypeslib.as_array(ptr, shape) print "wrong array", array.tolist()
if create external
instances using input lists of difference lengths, works expected. doing wrong here?
the problem numpy array garbage-collected , underlying memory freed, resulting in dangling pointer.
the solution keep reference underlying buffer
object:
def __init__(self, seq): array = np.array(seq, dtype=np.float64) self._buffer = array.data self.ptr = cast( array.ctypes.data_as(pointer(c_double)), c_void_p ) ...
now memory array freed when instance of external
holding reference gets deleted.
Comments
Post a Comment