当通过c线程从c线程调用时,malloc失败

时间:2012-02-06 12:44:02

标签: python multithreading ctypes

我正在使用Python的CType绑定到共享库;我有一个在这个库中注册的回调,它在库本身创建的线程的上下文中调用。我发现如果我在回调中调用libc.malloc()libc = cdll.LoadLibrary('libc.so.6')),它会返回虚假值。不是NULL,而是如果我取消引用它会导致段错误的地址。

任何人都可以向我提供有关可能发生的事情的任何见解,或者告诉我他们以同样的方式致电malloc(),并且它适用于他们。

2 个答案:

答案 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函数对象(或类,如果是方法)。