pythonctypes&;穿线

pythonctypes&;穿线,python,ctypes,Python,Ctypes,为了将其放到上下文中,我正在为C DLL创建一个包装器——相当复杂的用例,但请坚持我的观点 在我的包装类初始化期间,我为我的C DLL函数创建别名,以便我的类以后可以轻松地访问它们。我做的另一项任务是将类中函数的回调传递给DLL,DLL保存在静态变量中,稍后使用 最后,我生成了另一个线程,该线程在我的DLL中重复调用一个函数,该函数在执行过程中的不同时间点执行一些工作,需要使用在类的init阶段分配的回调函数回调Python程序 以这种方式调用回调时,我收到以下消息: WindowsError:

为了将其放到上下文中,我正在为C DLL创建一个包装器——相当复杂的用例,但请坚持我的观点

在我的包装类初始化期间,我为我的C DLL函数创建别名,以便我的类以后可以轻松地访问它们。我做的另一项任务是将类中函数的回调传递给DLL,DLL保存在静态变量中,稍后使用

最后,我生成了另一个线程,该线程在我的DLL中重复调用一个函数,该函数在执行过程中的不同时间点执行一些工作,需要使用在类的init阶段分配的回调函数回调Python程序

以这种方式调用回调时,我收到以下消息:

WindowsError: exception: access violation reading 0x00000001

我怀疑这与线程有关,因为当我在分配回调的同一线程中测试回调时,DLL可以成功地调用它,并且我的所有参数都传递给Python。是否对DLL中用于持久化回调的变量实施了某些保护?

来自ctypes上的Python文档:

回调函数的重要注意事项:

确保保留对CFUNCTYPE对象的引用,只要它们是从C代码中使用的。ctypes不会,如果您不这样做,它们可能会被垃圾收集,在进行回调时会使程序崩溃

如果您看到“访问冲突”或“分段错误”,并且正在处理回调,这很可能就是原因。正如J.F.Sebastian提到的,globals是一个选项,尽管我通常在我的类中维护一个对活动回调的引用列表


如果不涉及回调,请仔细检查包装中的类型。声明错误的类型可能会变得难看,很难理解。

在Python端保留对回调的引用,例如,将其分配给全局。我正在做什么,并且仍然继续做什么?查看回调的
\u objects
属性。它保留了对a的引用,该引用具有
pcl\u exec
C func、标志、转换器、restype和Python可调用。不要让它被垃圾收集,否则你会得到访问冲突(ctypes“方便地”处理Windows SEH异常…希望你只是记录它并让进程结束)。谢谢@J.F.Sebastian,我忘记了我DLL中的回调变量是指向Python创建的内存的