我正在使用libffi 库(版本 3.2.1)通过允许脚本编写者创建用于调用 API 函数的原型或定义与 API 兼容的回调函数来启用与脚本语言的 API 接口。
在 x64 上,Windows 上只使用一种调用约定;libffi中的WIN64。这与库中的闭包完美配合,脚本编写者可以轻松创建回调函数,可用于 EnumChildWindows(HWND, WNDENUMPROC, LPARAM) 等调用
但是,在 x86 上,使用由 LibFFI 和 STDCALL ABI 创建的闭包调用 EnumChildWindows 会导致发生堆栈溢出异常。根据报告的问题,这是由于在调用 trampoline 函数时错误分配了参数。(x86 stdcall (win32) 错误地对齐堆栈参数,win32 x86 stdcall 闭包:闭包调用后错误地恢复堆栈)。
我已经尝试应用这些问题报告中提到的补丁,但是它们似乎并没有解决我的测试用例的问题。我有另一个测试用例来确定它是否真的是参数对齐,方法是创建一个没有任何参数的回调函数;从外部二进制文件调用它。这个 STDCALL 函数被正确调用并且没有问题发生,因为不需要参数对齐。
在绝望的状态下,我尝试使用与 3.2.1 相同的工具链编译 libffi 存储库的提示版本,但是该版本抱怨不支持 x86 Windows 目标(sysv.S 中的 asm 语法错误)。由于 CRT 与生成的静态库的静态链接,我需要在 MSVC 中编译该库。
最后,我对解决方案的问题包括几个选项
- 有没有人有 3.2.1 的补丁来修复 Windows x86 上的 stdcall 问题
- 有谁知道用 MSVC 为 x86 目标编译提示版本的方法
- 谁能告诉我如何将 LibFFI 编译为具有完全静态链接依赖项的静态库(CRT/pthreads,我尝试使用 gcc -static ... -static-libgcc -lpthreads -lrt),因为我的尝试仍然产生“未解析的符号”关于即pthread
一个多星期以来,我一直在寻找解决方案,我假设我缺少一些明显的东西,因为许多项目都使用了该库。
谢谢你,
巴斯