开发者

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>}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜