Author: Jeremy Thurgood <[email protected]>
Branch: 
Changeset: r68766:1329fe522dfb
Date: 2014-01-19 19:21 +0200
http://bitbucket.org/pypy/pypy/changeset/1329fe522dfb/

Log:    fix for issue #1671, ctypes array-in-struct keepalive

diff --git a/lib_pypy/_ctypes/structure.py b/lib_pypy/_ctypes/structure.py
--- a/lib_pypy/_ctypes/structure.py
+++ b/lib_pypy/_ctypes/structure.py
@@ -2,6 +2,8 @@
 import _rawffi
 from _ctypes.basics import _CData, _CDataMeta, keepalive_key,\
      store_reference, ensure_objects, CArgObject
+from _ctypes.array import Array
+from _ctypes.pointer import _Pointer
 import inspect
 
 def names_and_fields(self, _fields_, superclass, anonymous_fields=None):
@@ -104,8 +106,11 @@
     def __set__(self, obj, value):
         fieldtype = self.ctype
         cobj = fieldtype.from_param(value)
-        if ensure_objects(cobj) is not None:
-            key = keepalive_key(self.num)
+        key = keepalive_key(self.num)
+        if issubclass(fieldtype, _Pointer) and isinstance(cobj, Array):
+            # if our value is an Array we need the whole thing alive
+            store_reference(obj, key, cobj)
+        elif ensure_objects(cobj) is not None:
             store_reference(obj, key, cobj._objects)
         arg = cobj._get_buffer_value()
         if fieldtype._fficompositesize is not None:
diff --git a/pypy/module/test_lib_pypy/ctypes_tests/test_keepalive.py 
b/pypy/module/test_lib_pypy/ctypes_tests/test_keepalive.py
--- a/pypy/module/test_lib_pypy/ctypes_tests/test_keepalive.py
+++ b/pypy/module/test_lib_pypy/ctypes_tests/test_keepalive.py
@@ -31,7 +31,17 @@
         assert p._objects == {}
         assert len(x._objects) == 1
         assert x._objects['0'] is p._objects
-        
+
+    def test_simple_structure_and_pointer_with_array(self):
+        class X(Structure):
+            _fields_ = [('array', POINTER(c_int))]
+
+        x = X()
+        a = (c_int * 3)(1, 2, 3)
+        assert x._objects is None
+        x.array = a
+        assert x._objects['0'] is a
+
     def test_structure_with_pointers(self):
         class X(Structure):
             _fields_ = [('x', POINTER(c_int)),
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to