我正在尝试使用Ctypes包装蓝牙堆栈。堆栈以异步方式工作,用户调用函数并在稍后回调中使用回调中的数据。为了处理Python端的回调,我像往常一样使用CFUNFTYPE机制。一切正常我能够发送和接收数据,使用整个API与所有结构几乎在C中。唯一的问题是,在一定数量的回调调用(例如收到275个数据包)后它失败 - 只是停止接收事件或导致访问冲突,内存读取和写入随机地址。当我在C中镜像相同的实现时,一切正常,所以问题必须发生在通往Python的路上。
的Python:
callback_type = CFUNCTYPE(None, c_int, c_int, c_int, c_void_p)
def bt_callback(event, service_id, function_id, data):
....callback stuff here.....
# keep reference to function object
callback = callback_type(bt_callback)
以下几行将函数对象传递给Init函数中的C端
status = BT_Init(byref(pSettings), byref(pStackSettings), callback)
其中BT_Init ctypes声明如下:
BT_Init = lib.Py_BT_Init
BT_Init.restype = c_int
BT_Init.argtypes = [POINTER(BT_Settings_t), POINTER(BT_StackSettings_t), callback_type]
我在原始API的顶部还有一个简单的C层,它允许我尝试不同的实现,在BT_Init的情况下它只是将参数传递给原始的Init函数
C:
int Py_BT_Init(BT_Settings_t * pSettings, BT_StackSettings_t * pStackSettings, void * pyCallback)
{
BTSTATUS_t status = BT_Init(pSettings, pStackSettings, pyCallback);
return (int)status;
}
我已经在三个不同的平台上测试了这个代码x86,ARM BeagleBone甚至是TI的OMAP35x以及各种Linux发行版,并得到了相同的结果 - 在一定数量的回调调用后崩溃。唯一的区别是崩溃前成功迭代的次数。 x86-275,ARM-374
这可能是什么原因?我的函数对象垃圾收集是否与某些线程问题有关?有没有人知道它可能是什么?