访问 .exe 导出函数时 Python ctypes 访问冲突
Posted
技术标签:
【中文标题】访问 .exe 导出函数时 Python ctypes 访问冲突【英文标题】:Python ctypes access violation when accessing an .exe exported function 【发布时间】:2017-08-26 19:41:45 【问题描述】:当通过 python 上的 ctypes 调用导出的 c++ 函数时,我遇到了访问冲突。
我将问题缩小到以下 c++ 函数:(在 vs2017 上编译)
#include <cstdio>
__declspec(dllexport) void x()
FILE* out = stdout; // After debugging, this is where the access violation happens.
调用函数时出现以下错误(与使用 vs 调试时显示的错误相同):
Python 代码:
ctypes.windll.<exe_name>.x()
错误:
OSError:异常:访问冲突写入 0x_some_address
关键是,上面是编译成EXE的。 (当我导出一个调用“主”入口点的函数时,整个事情就开始了)
在花了一些时间并尝试了一切之后,我尝试将上面的内容编译为 DLL,现在它可以按预期工作了。
所以问题是,有人可以向我解释导致问题的原因吗? 我知道(或多或少)内存管理差异,但不知道细节。
谢谢。
【问题讨论】:
您是说您尝试使用ctypes
调用.exe
?请显示发生错误的 Python 代码。还请显示函数的导出,以及调用main
的函数代码。
添加了 py 代码。显示了函数的导出。这是 vs,所以 dllexport 就是将它添加到 vtable 的原因。调用 main 的函数无关紧要。我提出的问题是一种简洁的方式,重现结果所需的所有信息都在这里。我只是为了一些背景而提到它。
dllexport
与 vtable 无关。 vtable 是用于支持虚函数的 C++ 特定设备,它被 VS 以外的其他实现使用。 dllexport
将函数名称存储在 DLL 的导出表中,是特定于 Windows 的,也用于 C 程序中。在 DLL 中,你有没有 DllMain()
函数?
你是对的。当然,我指的是导出表。我没有 DllMain。由于它链接到 CRT,我猜它有 CRTs 入口点。也许这说明了什么。
“重现结果所需的所有信息都在这里”。没有。该函数不能编译...作为 EXE 或 DLL。
【参考方案1】:
这篇文章似乎为这个问题提供了足够的背景信息和可能的解决方案: https://www.codeproject.com/Articles/1045674/Load-EXE-as-DLL-Mission-Possible
将 EXE 作为 DLL 加载的主要区别是:
CRT 未初始化,包括任何全局变量,并且 导入地址表配置不正确,这意味着对导入函数的所有调用都会崩溃。
【讨论】:
换句话说,将其构建为 DLL :^) 问题已经指出了这一点。我知道解决方案是什么,但我要求解释差异。 我看到了,我只是在评论使它工作的复杂性。以上是关于访问 .exe 导出函数时 Python ctypes 访问冲突的主要内容,如果未能解决你的问题,请参考以下文章