来自其他线程的ctypes异步回调
ctypes asynchronous callback from other thread
我正在尝试从 C 线程接收异步回调,但是 Python 每次调用此类回调时都会崩溃。
这是 C 回调原型:
/*! Type declaration for the frame ready callback function.
@sa IC_SetFrameReadyCallback
@sa IC_SetCallbacks
@retval IC_SUCCESS Callback was set successfully
@retval IC_ERROR An error occurred, e.g. hGrabber is NULL.*/
typedef void (*FRAME_READY_CALLBACK)
(HGRABBER hGrabber, unsigned char* pData, unsigned long frameNumber, void* );
这是注册回调的 C 函数:
/*! Enable frame ready callback.
@param hGrabber Handle to a grabber object.
@param cb Callback function of type FRAME_READY_CALLBACK
@param x1_argument_in_void_userdata Pointer to some userdata.
@retval IC_SUCCESS Callback was set successfully
@retval IC_ERROR An error occurred, e.g. hGrabber is NULL.
@sa FRAME_READY_CALLBACK*/
int AC IC_SetFrameReadyCallback(
HGRABBER hGrabber,
FRAME_READY_CALLBACK cb,
void* x1_argument_in_void_userdata);
最后,这是我的 Python 代码的一部分:
FRAME_READY_CALLBACK = CFUNCTYPE(c_int, ICGrabber, POINTER(c_ubyte), c_ulong, c_void_p)
...
library = windll.LoadLibrary('tisgrabber_x64')
...
IC_SetFrameReadyCallback = library.IC_SetFrameReadyCallback
IC_SetFrameReadyCallback.restype = c_int
IC_SetFrameReadyCallback.argtypes = [ICGrabber, FRAME_READY_CALLBACK, c_void_p]
...
def frame_ready(icGrabber, data, frameNumber, unused):
print "oh"
#print "Frame", frameNumber, "ready!!!"
return 1
IC_InitLibrary(0) #library init function
...
IC_SetFrameReadyCallback(hGrabber, FRAME_READY_CALLBACK(frame_ready), None)
...
IC_SoftwareTrigger() #send signal
time.sleep(2) # while sleeping, the C thread calls the.. frame_ready callback
你猜怎么着?睡觉时,它崩溃了!
这是错误的代码:
IC_SetFrameReadyCallback(hGrabber, FRAME_READY_CALLBACK(frame_ready), None)
这是有效的:
cframe_ready = FRAME_READY_CALLBACK(frame_ready)
IC_SetFrameReadyCallback(grab, cframe_ready, None)
问题:
我没有保留对回调的引用,所以 Python 垃圾收集器清理了它。
我正在尝试从 C 线程接收异步回调,但是 Python 每次调用此类回调时都会崩溃。
这是 C 回调原型:
/*! Type declaration for the frame ready callback function.
@sa IC_SetFrameReadyCallback
@sa IC_SetCallbacks
@retval IC_SUCCESS Callback was set successfully
@retval IC_ERROR An error occurred, e.g. hGrabber is NULL.*/
typedef void (*FRAME_READY_CALLBACK)
(HGRABBER hGrabber, unsigned char* pData, unsigned long frameNumber, void* );
这是注册回调的 C 函数:
/*! Enable frame ready callback.
@param hGrabber Handle to a grabber object.
@param cb Callback function of type FRAME_READY_CALLBACK
@param x1_argument_in_void_userdata Pointer to some userdata.
@retval IC_SUCCESS Callback was set successfully
@retval IC_ERROR An error occurred, e.g. hGrabber is NULL.
@sa FRAME_READY_CALLBACK*/
int AC IC_SetFrameReadyCallback(
HGRABBER hGrabber,
FRAME_READY_CALLBACK cb,
void* x1_argument_in_void_userdata);
最后,这是我的 Python 代码的一部分:
FRAME_READY_CALLBACK = CFUNCTYPE(c_int, ICGrabber, POINTER(c_ubyte), c_ulong, c_void_p)
...
library = windll.LoadLibrary('tisgrabber_x64')
...
IC_SetFrameReadyCallback = library.IC_SetFrameReadyCallback
IC_SetFrameReadyCallback.restype = c_int
IC_SetFrameReadyCallback.argtypes = [ICGrabber, FRAME_READY_CALLBACK, c_void_p]
...
def frame_ready(icGrabber, data, frameNumber, unused):
print "oh"
#print "Frame", frameNumber, "ready!!!"
return 1
IC_InitLibrary(0) #library init function
...
IC_SetFrameReadyCallback(hGrabber, FRAME_READY_CALLBACK(frame_ready), None)
...
IC_SoftwareTrigger() #send signal
time.sleep(2) # while sleeping, the C thread calls the.. frame_ready callback
你猜怎么着?睡觉时,它崩溃了!
这是错误的代码:
IC_SetFrameReadyCallback(hGrabber, FRAME_READY_CALLBACK(frame_ready), None)
这是有效的:
cframe_ready = FRAME_READY_CALLBACK(frame_ready)
IC_SetFrameReadyCallback(grab, cframe_ready, None)
问题:
我没有保留对回调的引用,所以 Python 垃圾收集器清理了它。