问题描述
我正在使用 WINE(在 64 位 Linux 上)运行一个 32 位 Windows 应用程序,该应用程序加载一个 DLL (LoadLibrary
)。我想为该环境重写 DLL 并使用 winegcc
/winebuild
编译它,而不修改原始程序。我对支持 32 位 Linux 主机不感兴趣,但 DLL 本身需要以 32 位 Windows 为目标,如 answer to another question 中所述,process interoperability 需要它:
在 64 位 Windows 上,64 位进程无法加载 32 位动态链接库 (DLL)。
此外,32 位进程无法加载 64 位 DLL。
但是,在为 32 位 Windows 构建时,winegcc
(使用 -m32
标志)会生成一个 x86“DLL 包装”共享对象,该共享对象链接到其他 32 位版本的 Linux 库( 例如 libwinecrt0.a
)。这不是理想的行为,因为它要求 Linux 主机拥有那些阻碍 DLL 轻松分发的 32 位库。此外,链接器本身阻止了尝试手动链接库的 64 位版本,并出现预期错误:
/usr/bin/ld: relocatable linking with relocations from
format elf64-x86-64 to format elf32-i386 is not supported
现在,我知道 x86 和 amd64/x86_64 之间的 ISA(甚至 ABI?)存在固有差异,导致 32 位 Windows 应用程序无法加载 64 位 DLL 并且 GCC 链接器拒绝链接 32-位 Linux 共享对象到 64 位库。这种不兼容性是现代 CPU 能够放置在“x86 mode”中的原因,允许 32 位代码运行。反过来,这种模式切换需要常规用户空间程序没有的权限,这意味着在库中不可能有 x86_64 到 x86 兼容层(请参阅 Why cannot 64-bit shared libraries be used by 32-bit code?);是对的吗?如果没有,怎么办?
话虽如此,我注意到 32 位 Windows 应用程序能够由 64 位 WINE 运行,而无需 (AFAIK) 需要任何 32 位 Linux 库。因此,我猜想 WINE 通过重新实现 WoW64 来实现这一点,并且通过这样做,在 WINE 环境中包含任何“32 位”。那么我有没有办法在我的 DLL 中利用它?
我在这里提出的观点是,这不是一个常规的“从 32 位代码调用 64 位库”问题,因为它涉及操作系统顶部的一个(甚至两个?)额外层,我想以某种方式利用它。我考虑过但不满足所有要求的选项是:
- 使用
winegcc -m32
构建 DLL 使LoadLibrary
成功,但链接到 32 位 Linux 库 - 使用针对 64 位 Linux 库的
winegcc -m64
链接构建 DLL,但无法从 32 位 Windows 中LoadLibrary
- 使用 MinGW(或任何 Windows 本地编译器)构建 DLL 会利用 WoW64,因此不需要 32 位 Linux 库,但完全阻止我使用 Linux 代码,这是在第一名
我还有什么其他选择?包装代码?特定的系统调用? WINE 中的特定功能? ...?
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)