我使用 msys 和编译标志
-s -fomit-frame-pointer -fno-unwind-tables -fdata-sections -ffunction-sections -fvisibility=hidden -fvisibility-inlines-hidden -fstack-protector -fno-math-errno -Wl,--gc-sections -Wl,--strip-all -Wl,--add-stdcall-alias
编译了本机库,并在 CMake中添加了
target_link_libraries(myapp -static)
一切正常,但是当我尝试在 Windows Server 2019 Standard X64 上运行我的本机库时,出现错误
Exception in thread "main" java.lang.RuntimeException: java.lang.UnsatisfiedLinkError: C:\Users\user\Desktop\lib\native.dll: A dynamic link library (DLL) initialization routine failed
at com.basic.app.SyntheticProtectedApplication.main(Unknown Source)
Caused by: java.lang.UnsatisfiedLinkError: C:\Users\user\Desktop\lib\native.dll: A dynamic link library (DLL) initialization routine failed
at java.base/jdk.internal.loader.NativeLibraries.load(Native Method)
at java.base/jdk.internal.loader.NativeLibraries$NativeLibraryImpl.open(NativeLibraries.java:388)
at java.base/jdk.internal.loader.NativeLibraries.loadLibrary(NativeLibraries.java:232)
at java.base/jdk.internal.loader.NativeLibraries.loadLibrary(NativeLibraries.java:174)
at java.base/java.lang.ClassLoader.loadLibrary(ClassLoader.java:2394)
at java.base/java.lang.Runtime.load0(Runtime.java:755)
at java.base/java.lang.System.load(System.java:1953)
at com.basic.app.API$NativeBridge.<clinit>(API.java:170)
at com.basic.app.API.initialize(API.java:59)
... 1 more
我尝试检查我是否没有链接任何动态库
但似乎我没有任何外部库,依赖项应用程序显示所有模块均已正确加载。我的海湾合作委员会版本:
$ gcc --version
gcc.exe (Rev3, Built by MSYS2 project) 13.2.0
Copyright (C) 2023 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
这里可能存在什么问题?我希望我的库与所有 Windows 版本兼容。
问题与JNI无关,甚至返回假错误代码。
我使用 WinDbg 检查到底是什么问题,我发现
(1868.1690): Illegal instruction - code c000001d (first chance)
(1868.1690): Illegal instruction - code c000001d (!!! second chance !!!)
native!LoginLicenseKey+0x35484:
00007ffa48ad4834 c4c1f96ece vmovq xmm1,r14
我发现这与cpu指令有关,我将cpu从kvm64更改为host,问题就消失了
但这不是通用解决方案,我找到了更好的解决方案。在 gcc 中禁用现代 cpu 指令就足够了:
-mno-avx -msse3 -march=core2