我正在使用libffi library (version 3.2.1)通过允许脚本编写者创建用于调用API函数或定义与API兼容的回调函数的原型来从脚本语言启用API接口。
在x64上,Windows上仅使用一种调用约定。 libffi中的WIN64。这与库中的闭包完美配合,脚本编写器可以轻松创建可在诸如EnumChildWindows(HWND,WNDENUMPROC,LPARAM)之类的调用中使用的回调函数。
但是,在x86上,使用LibFFI和STDCALL ABI创建的闭包调用EnumChildWindows会导致发生堆栈溢出异常。根据报告的问题,这是由于对蹦床函数的调用中的参数分配错误。 (x86 stdcall (win32) incorrectly aligns stack arguments,win32 x86 stdcall closure: incorrectly restored stack after closure call)。
我已经尝试应用那些问题报告中提到的补丁,但是它们似乎并不能解决我的测试案例中的问题。我还有另一个测试用例,可以通过创建没有任何参数的回调函数来确定它是否真的是参数对齐;从外部二进制文件调用它。正确调用此STDCALL函数,不会发生任何问题,因为不需要参数对齐。
在绝望状态下,我尝试使用与3.2.1相同的工具链编译libffi存储库的最新版本,但是该版本抱怨不支持x86 Windows目标(sysv.S中的asm语法错误)。由于CRT与生成的静态库的静态链接,我需要在MSVC中进行编译的库。
最后,我要解决的问题包括几个选项
有没有人为Windows x86上的stdcall提供3.2.1补丁来解决此问题
有谁知道用x86目标的MSVC编译提示版本的方法
谁能告诉我如何将LibFFI编译为具有完全静态链接的依赖关系的静态库(CRT / pthreads,我尝试使用gcc -static ... -static-libgcc -lpthreads -lrt),因为我的尝试仍然会产生“未解析的符号”关于即pthread
我一直在寻找解决方案一个多星期,并且我假设我遗漏了一些明显的东西,因为许多项目中都使用了该库。
谢谢,
巴斯
最佳答案
在进一步的研究中,我发现Java Native Access中使用了libffi的分支。此版本的LibFFI包含我一直在寻找的修复程序,并且x86 stdcall闭包已成功执行。此版本的LibFFI可成功与MSVCC一起编译。
这是我原始问题中可能选项列表中的第一个解决方案。
关于c - x86 Windows上STDCALL ABI的关闭导致LibFFI 3.2.1出现堆栈溢出异常,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/48703662/