我有一个问题,我使用 mxe (x86_64-w64-mingw32.shared) 在 Linux 上构建并链接 Windows 应用程序,构建和链接运行良好。然后我复制粘贴所有有用的 dll(它们都是交叉编译的,除了 x64-msvcrt-ruby230.dll,它是我从官方 Windows 安装程序获得的)。
我用 wine 测试了我的程序,没问题,它工作起来就像一个魅力,我发现与 Linux 版本没有任何区别。但是,一旦我将所有内容放入测试虚拟机(virtualbox 内的 windows10 64 位)中,我就会收到错误消息:
无法在动态链接库 D:\libpng16-16.dll 中定位过程入口点 inflateValidate。
libpng16-16.dll 就在那里,当我对它进行对象转储时(在 Linux 中):
objdump -x libpng16-16.dll | grep 膨胀
3a9f4 60 inflate
3aa00 66 inflateEnd
3aa10 69 inflateInit2_
3aa20 73 inflateReset
3aa30 74 inflateReset2
3aa40 80 inflateValidate
[642](sec 1)(fl 0x00)(ty 20)(scl 3) (nx 0) 0x0000000000013be0 png_inflate_claim
[654](sec 1)(fl 0x00)(ty 20)(scl 2) (nx 0) 0x0000000000014280 png_zlib_inflate
[655](sec 1)(fl 0x00)(ty 20)(scl 3) (nx 0) 0x00000000000142d0 png_inflate.constprop.6
[657](sec 1)(fl 0x00)(ty 20)(scl 3) (nx 0) 0x0000000000014680 png_inflate_read.part.3.constprop.8
[3002](sec 1)(fl 0x00)(ty 20)(scl 2) (nx 0) 0x0000000000021b08 inflateReset2
[3023](sec 1)(fl 0x00)(ty 20)(scl 2) (nx 0) 0x0000000000021b28 inflate
[3081](sec 1)(fl 0x00)(ty 20)(scl 2) (nx 0) 0x0000000000021b00 inflateValidate
[3088](sec 8)(fl 0x00)(ty 0)(scl 2) (nx 0) 0x0000000000000578 __imp_inflateReset2
[3119](sec 8)(fl 0x00)(ty 0)(scl 2) (nx 0) 0x0000000000000568 __imp_inflateInit2_
[3138](sec 8)(fl 0x00)(ty 0)(scl 2) (nx 0) 0x0000000000000560 __imp_inflateEnd
[3143](sec 1)(fl 0x00)(ty 20)(scl 2) (nx 0) 0x0000000000021b10 inflateReset
[3155](sec 8)(fl 0x00)(ty 0)(scl 2) (nx 0) 0x0000000000000558 __imp_inflate
[3162](sec 8)(fl 0x00)(ty 0)(scl 2) (nx 0) 0x0000000000000580 __imp_inflateValidate
[3197](sec 8)(fl 0x00)(ty 0)(scl 2) (nx 0) 0x0000000000000570 __imp_inflateReset
[3244](sec 1)(fl 0x00)(ty 20)(scl 2) (nx 0) 0x0000000000021b20 inflateEnd
[3253](sec 1)(fl 0x00)(ty 20)(scl 2) (nx 0) 0x0000000000021b18 inflateInit2_
显然符号 __imp_inflateValidate 存在,那么我缺少什么吗?有人知道如何解决这个问题吗?
提前致谢
刚刚偶然发现了同样的问题。结果发现这是 PATH 环境变量中存在冲突的 dll 文件。尝试使用
ldd
命令找出哪些 dll 文件可能可疑。
例如,就我而言,罪魁祸首是来自英特尔无线软件的 zlib1.dll。
E:\samples\sfmlSound>ldd sfmlSound.exe ntdll.dll => /c/WINDOWS/SYSTEM32/ntdll.dll (0x7ffee3e70000) KERNEL32.DLL => /c/WINDOWS/System32/KERNEL32.DLL (0x7ffee3030000) ... zlib1.dll => /c/Program Files/Intel/WiFi/bin/zlib1.dll (0x7ffed0f10000) ...
解决冲突后,程序将正确加载。
就我而言,我替换了 libpng16-16 文件并且有效。
我在尝试运行一些基于
libpng16-16.dll
的代码时偶然发现了类似的问题。显然 SDL_Image 的某些构建版本已损坏:https://github.com/libsdl-org/SDL_image/issues/131,在本文中讨论:
https://discourse.libsdl.org/t/sdl2-image-fails-loading-libpng-on-latest-versions-when-cross-compiling/24494/
对我来说,它可以回滚到旧版本并确保
libpng16-16.dll
和 zlib1.dll
都位于可执行文件的文件夹中。 (当然还有其他所需的DLL)
SDL_image
的版本可以在这里找到:https://www.libsdl.org/projects/SDL_image/release/
引自相关 MINGW 问题(强调我的):
所以我找到了原因。 Intel 在
中引入了他们自己的zlib1.dll
,并将这个目录添加到 PATH 中。因此,每当链接到 zlib 的应用程序尝试在 PATH 中没有C:\Program Files\Intel\WiFi\bin\
的情况下执行时,它都会尝试加载这个不同版本的 zlib,但不包含该方法。真正的解决方案是刺探英特尔并告诉他们停止做愚蠢的事情,比如用自己的东西困扰系统范围的路径,但无论如何。 只需将 mingw64 zlib1.dll 复制到应用程序目录中即可。C:\msys64\mingw64\bin
或者,只需从您的路径中删除英特尔 WiFi 内容即可。根据您的设置,也可以将其移至 PATH 的末尾,以便 PATH 的所有其他目录优先。