Python: ctypes pointer to local variables; how to ensure they don't get freed?
I have some code somewhat similar to this:
def castArgToCtype(arg, ctyp):
if issubclass(ctyp, _ctypes._Pointer): return createPtr(arg, ctyp)
return ctyp(arg)
def createPtr(arg, ctyp):
assert isinstance(arg, (list,tuple))
assert issubclass(ctyp, _ctypes._Pointer)
o = (ctyp._type_ * (len(arg) + 1))()
for i in x开发者_如何学Gorange(len(arg)):
o[i] = castArgToCtype(arg[i], ctyp._type_)
op = ctypes.cast(ctypes.addressof(o), ctyp)
# TODO: what when 'o' goes out of scope and freed?
return op
And I am calling it like createPtr((1,2,3), ctypes.POINTER(ctypes.c_int))
.
How can I ensure that the ctpes array o
I create there is not freed as long as op
is not freed?
I have seen the attribute op._objects
which even seem to be there for this purpose but it is readonly.
This seems to work:
import ctypes, _ctypes
def castArgToCtype(arg, ctyp):
if issubclass(ctyp, _ctypes._Pointer): return createPtr(arg, ctyp)
return ctyp(arg)
def createPtr(arg, ctyp):
assert isinstance(arg, (list,tuple))
assert issubclass(ctyp, _ctypes._Pointer)
o = (ctyp._type_ * (len(arg) + 1))()
for i in xrange(len(arg)):
o[i] = castArgToCtype(arg[i], ctyp._type_)
op = ctypes.pointer(o)
op = ctypes.cast(op, ctyp)
return op
a = createPtr((1,2,3), ctypes.POINTER(ctypes.c_int))
print a, a[0], a[1], a[2], a._objects
Output:
<__main__.LP_c_int object at 0x105dc6680> 1 2 3 {'1': <__main__.c_int_Array_4 object at 0x105dc6560>, '0': {}, 4393297392: <__main__.LP_c_int_Array_4 object at 0x105dc65f0>}
The extra iteration is not needed. Just create the array object and cast it to the pointer required.
import ctypes,_ctypes
def castArgToCtype(arg, ctyp):
if issubclass(ctyp, _ctypes._Pointer): return createPtr(arg, ctyp)
return ctyp(arg)
def createPtr(arg, ctyp):
assert isinstance(arg, (list,tuple))
assert issubclass(ctyp, _ctypes._Pointer)
return ctypes.cast((ctyp._type_ * len(arg))(*arg),ctyp)
a = castArgToCtype((1,2,3),ctypes.POINTER(ctypes.c_int))
print a,a[0],a[1],a[2],a._objects
Output
<x.LP_c_long object at 0x00EB7760> 1 2 3 {15431440: <ctypes._endian.c_long_Array_3 object at 0x00EB7710>}
精彩评论