python cffi在回调后崩溃

python cffi在回调后崩溃,python,ctypes,cpython,python-cffi,Python,Ctypes,Cpython,Python Cffi,我有一个专有的dll,它与usb设备接口,ctypes接口工作正常,但调用回调后cffi接口崩溃。 如果函数SwitchOn(6)找到设备,则应返回指向结构的指针;如果未找到设备,则返回NULL;如果未找到设备,则返回errno=10调用的错误回调 我使用的是python27,py33的行为与之相同(需要删除“导入线程”才能运行) 我用对了吗?如何调试它 尝试根据我的需要调整doc的示例,如abarnert所建议的那样。它仍然崩溃。我做得对吗 >>> cffi.__versio

我有一个专有的dll,它与usb设备接口,ctypes接口工作正常,但调用回调后cffi接口崩溃。 如果函数SwitchOn(6)找到设备,则应返回指向结构的指针;如果未找到设备,则返回NULL;如果未找到设备,则返回errno=10调用的错误回调

我使用的是python27,py33的行为与之相同(需要删除“导入线程”才能运行)

我用对了吗?如何调试它

尝试根据我的需要调整doc的示例,如abarnert所建议的那样。它仍然崩溃。我做得对吗

>>> cffi.__version__
'0.7.2'
ctypes示例输出:

10288
(10288, 10L, 1L)
0
4504
(4504, 10L, 1L)
cffi示例输出:

10288
(10288, 10L, 1L)
0
4504
(4504, 10L, 1L)
和崩溃

cffi_crash.py ctypes\u no\u crash.py cffi_indirection.py 根据文件:

Windows:您还不能指定回调的调用约定…请使用间接寻址

而您的崩溃(从函数返回后立即发生)看起来正是通过传递
cdecl
函数并将其作为
stdcall
函数调用而得到的结果:调用方(可能是C库中的
开关
函数)期望被调用方(CFFI对
error
函数的包装)来清理堆栈;被调用方希望调用方清理堆栈…因此没有人清理堆栈,因此当
开关打开
尝试返回时,它返回到一个参数或局部变量或其他垃圾,而不是它的调用方


紧接着,这些文档展示了如何“使用间接寻址”,也就是说,它们意味着编写一个C包装,您可以
ffi.verify
(它们展示了如何传递varargs回调,但想法是一样的)

函数返回时崩溃看起来就像调用
cdecl
函数时遇到的情况,就像调用
stdcall
函数一样,反之亦然。如果可以运行调试器(如MSVC、windbg等;而不是Python调试器)您应该能够验证是调用后堆栈清理非常容易地完成了所有工作。我没有dll的源代码。在这种情况下如何编写包装器?@Mindles:您不需要dll的源代码。您是否单击了链接并查看了示例包装器?它不需要访问任何C库的源代码是的,它会和你的一起使用。为什么你认为你的会呢?
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)