通过ctypes从C线程调用时malloc失败
我正在使用Python的CTypes来连接一个共享库;我在这个库中注册了一个回调函数,这个回调是在库自己创建的线程中被调用的。我发现,如果我在回调函数中调用libc.malloc()
(libc = cdll.LoadLibrary('libc.so.6')
),它返回的值是错误的。不是NULL
,而是一个地址,如果我试图使用这个地址,就会导致程序崩溃。
有没有人能告诉我这可能是什么原因,或者说他们也以同样的方式调用malloc()
,并且一切正常。
2 个回答
0
下面的代码在Windows上可以正常运行。在Linux上应该也差不多。它甚至可以在32位系统上运行,而不需要明确设置argtypes/restype
这些属性。
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)
这种装饰器的写法会在模块(或者类,如果是方法的话)存在的期间,把Python的函数对象替换成ctypes的回调对象。
1
你有没有正确地标注malloc调用,让ctypes知道它应该返回指针而不是整数?(如果你是在64位的机器上工作,这一点尤其重要。)