我正在使用Python的CType绑定到共享库;我有一个在这个库中注册的回调,它在库本身创建的线程的上下文中调用。我发现如果我在回调中调用libc.malloc()
(libc = cdll.LoadLibrary('libc.so.6')
),它会返回虚假值。不是NULL
,而是如果我取消引用它会导致段错误的地址。
任何人都可以向我提供有关可能发生的事情的任何见解,或者告诉我他们以同样的方式致电malloc()
,并且它适用于他们。
答案 0 :(得分:1)
你是否正确地对malloc调用进行了正确的操作,以便ctypes知道它应该返回指针而不是整数? (如果你正在使用64位盒子,那么双重呢?)
答案 1 :(得分:0)
以下代码适用于Windows。应该在Linux上类似。它甚至应该在没有设置显式argtypes/restype
属性的情况下工作,至少在32位系统上是这样。
from ctypes import *
crt = CDLL('msvcrt')
malloc = crt.malloc
malloc.argtypes = [c_size_t]
malloc.restype = c_void_p
free = crt.free
free.argtypes = [c_void_p]
free.restype = None
n = cast(malloc(10),POINTER(c_ubyte))
for i in range(10):
print '{:02X}'.format(n[i]),
free(n)
由于您提到了回调,因此请确保在其使用寿命期间保留对回调的引用。这意味着不要把它称为:
set_callback(CFUNCTYPE(...)(callback_func))
设置回调后立即销毁CFUNCTYPE对象。而是做:
@CFUNCTYPE(...)
def callback_func(...)
...
set_callback(callback_func)
这个装饰器表单用ctypes回调对象替换模块生命周期的Python函数对象(或类,如果是方法)。