在 x86 Windows 上使用 STDCALL ABI 关闭会导致 LibFFI 3.2.1 出现堆栈溢出异常

Closures with the STDCALL ABI on x86 Windows cause Stack Overflow exceptions with LibFFI 3.2.1

我正在使用 libffi library (version 3.2.1) 从脚本语言启用 API 接口,方法是允许脚本编写者创建用于调用 API 函数或定义 API- 的原型兼容的回调函数。

在 x64 上,Windows 上只使用一种调用约定; libffi 中的 WIN64。这与库中的闭包完美配合,脚本编写者可以轻松创建可用于 EnumChildWindows(HWND, WNDENUMPROC, LPARAM)

等调用的回调函数

然而,在 x86 上,使用 LibFFI 使用 STDCALL ABI 创建的闭包调用 EnumChildWindows 会导致发生堆栈溢出异常。根据报告的问题,这是由于在调用 trampoline 函数时错误分配了参数。 (x86 stdcall (win32) incorrectly aligns stack arguments, win32 x86 stdcall closure: incorrectly restored stack after closure call).

我已经尝试应用那些问题报告中提到的补丁,但是它们似乎没有解决我的测试用例的问题。我有另一个测试用例来确定它是否真的是参数对齐,通过创建一个没有任何参数的回调函数;从外部二进制文件调用它。此 STDCALL 函数被正确调用并且没有出现任何问题,因为不需要参数对齐。

在绝望的状态下,我尝试使用我用于 3.2.1 的相同工具链编译 libffi 存储库的尖端版本,但是该版本抱怨不支持 x86 windows 目标(错误的 asm 语法sysv.S)。由于 CRT 到生成的静态库的静态链接,我需要库在 MSVC 中编译。

最后,我的问题解决方案包含几个选项

一个多星期以来我一直在寻找解决方案,并且我假设我遗漏了一些明显的东西,因为许多项目都使用了该库。

谢谢,
巴斯

在进一步的研究中,我发现 Java Native Access 中使用了 libffi 的一个分支。此版本的 LibFFI 包含我正在寻找的修复程序,并且成功执行了 x86 stdcall 闭包。此版本的 LibFFI 使用 MSVCC 成功编译。

这算作我原始问题中可能选项列表中的第一个解决方案。