我使用Python的CType綁定到共享庫;我有一個回調註冊到這個庫,這是在庫本身創建的線程的上下文中調用的。我發現如果我在回調中調用libc.malloc()
(libc = cdll.LoadLibrary('libc.so.6')
),它會返回虛假值。不是NULL
,而是一個地址,如果我將其解引用,會導致段錯誤。從c線程通過ctypes調用malloc失敗
任何人都可以提供任何有關可能發生的事情的信息,或者告訴我他們以同樣的方式調用malloc()
,並且它適用於他們。
我使用Python的CType綁定到共享庫;我有一個回調註冊到這個庫,這是在庫本身創建的線程的上下文中調用的。我發現如果我在回調中調用libc.malloc()
(libc = cdll.LoadLibrary('libc.so.6')
),它會返回虛假值。不是NULL
,而是一個地址,如果我將其解引用,會導致段錯誤。從c線程通過ctypes調用malloc失敗
任何人都可以提供任何有關可能發生的事情的信息,或者告訴我他們以同樣的方式調用malloc()
,並且它適用於他們。
你是否正確地調整了malloc調用,以便ctypes知道它應該返回指針而不是整數? (如果你正在使用一個64位的盒子,那麼這樣翻兩翻?)
下面的代碼適用於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函數對象(或類,如果一個方法)。