Python 调用 DLL 时报错 "WindowsError: exception: access violation reading 0x00000004

3 投票
1 回答
4499 浏览
提问于 2025-04-17 13:40

我有一个用Python写的应用程序。

这个应用程序通过一些函数调用一个DLL(使用ctypes),这个DLL又调用Python的C API中的一些函数,来加载并运行一个(不同的)Python模块。这导致出现了WindowsError: exception: access violation reading 0x00000004的错误。通过一些调试,我发现这个访问冲突发生在调用Python C API的时候。

我知道这个DLL在独立运行时能够成功加载Python模块,并且能够正常完成,但当它从Python应用程序中运行时,就出现了这个访问冲突的错误。

我最开始想,也许我应该在DLL中使用Py_NewInterpreter来为这些Python模块函数创建一个新的独立空间来运行。这看起来很方便,因为应用程序和DLL中的模块不需要共享任何数据。http://docs.python.org/2/c-api/init.html#Py_NewInterpreter

然而,我最初对Py_NewInterpreter的测试并不成功,反而出现了更多错误并崩溃。

所以我的问题是,我应该如何实现这个功能?我需要做些什么才能让DLL成功加载Python模块?

1 个回答

1

这看起来像是在解引用一个空指针,也就是说,你有一个指向结构体或类的指针,但它是空的,然后你试图读取它的某个部分。可以在代码中加一些assert()来确保你不会漏掉任何空指针。还要注意,Python的C API在出现异常时通常会返回空。

也就是说,你有一个Python程序通过ctypes导入了一个DLL。这个DLL又通过Python的C API嵌入了一个Python解释器,对吧?如果我没记错的话,这样实际上在一个进程中就有两个解释器实例。问题是,这两个解释器之间的全局对象是共享的,但可能没有协调好。

我建议你写一个合适的Python(包装)模块,而不是用ctypes来导入DLL。同时,我还建议你在Python用户邮件列表上询问一下,这种设置是否可行,以及为什么可行或不可行。如果你更喜欢的话,还有一个新闻网关可以使用。

撰写回答