我有一个与 USB 设备接口的专有 dll,它的 ctypes 接口工作正常,但 cffi 在调用回调后崩溃。如果找到设备,函数 SwitchOn(6) 应该返回指向结构的指针,如果没有,则返回 NULL,如果它没有找到设备错误回调,则使用 errno=10 调用。
我正在使用 python27,py33 的行为相同(需要删除“导入线程”才能运行)
我用对了吗?我该如何调试它?
按照abarnert的建议,尝试根据我的需要调整 doc 的示例。它仍然崩溃。我做对了吗?
>>> cffi.__version__
'0.7.2'
ctypes 示例输出:
10288
(10288, 10L, 1L)
0
cffi 示例输出:
4504
(4504, 10L, 1L)
和崩溃
cffi_crash.py
import thread
def error(errno, critical):
print(thread.get_ident(), errno, critical)
from cffi import FFI
ffi = FFI()
ffi.cdef('''
void* SwitchOn(int FPort);
typedef void(*type_func_user_error)(unsigned int, unsigned int);
void SetErrorFunction(type_func_user_error);
''')
eeg_dll = ffi.dlopen("EEG4DLL.dll")
err_cb = ffi.callback('type_func_user_error', error)
eeg_dll.SetErrorFunction(err_cb)
print(thread.get_ident())
x = eeg_dll.SwitchOn(6)
print(x)
ctypes_no_crash.py
import thread
def error(errno, critical):
print(thread.get_ident(), errno, critical)
import ctypes
from ctypes import c_uint, WINFUNCTYPE
eeg_dll = ctypes.windll.EEG4DLL
func_user_error = WINFUNCTYPE(None, c_uint, c_uint)
SetErrorFunction = eeg_dll.SetErrorFunction
SetErrorFunction.argtypes = [func_user_error]
SetErrorFunction.restype = None
err_cb = func_user_error(error)
eeg_dll.SetErrorFunction(err_cb)
print(thread.get_ident())
x = eeg_dll.SwitchOn(6)
print(x)
cffi_indirection.py
def error(errno, critical):
print(errno, critical)
from cffi import FFI
ffi2 = FFI()
ffi2.cdef('''
void (*python_callback)(unsigned int, unsigned int);
void *const c_callback;
''')
wr = ffi2.verify('''
static void(*python_callback)(unsigned int x, unsigned int y);
static void c_callback(unsigned int x, unsigned int y) {
python_callback(x, y);
}
''')
err_cb = ffi2.callback('void(unsigned int, unsigned int)', error)
wr.python_callback = err_cb
ffi = FFI()
ffi.cdef('''
void* SwitchOn(int FPort);
typedef void(*type_func_user_error)(unsigned int, unsigned int);
void SetErrorFunction(type_func_user_error);
''')
eeg_dll = ffi.dlopen("EEG4DLL.dll")
eeg_dll.SetErrorFunction(wr.c_callback)
x = eeg_dll.SwitchOn(6)
print(x)