一、前因
在windows下用cmake+VS编译了一个jni动态库,再使用java测试程序调用这个动态库的时候报错:“%1 不是有效的win32应用程序”
对于这类问题,一般从以下几个方面考虑:
- 动态库文件损坏
- 动态库或者其依赖库文件路径错误导致找不到。(不过这种动态库本身路径错误一般会报“找不到”)
- 动态库架构与系统架构或者JDK架构不一致
- 动态库的依赖库架构不匹配
那么从这几方面考虑,一一进行排查就涉及到了一些相关的命令。
一、设置临时环境变量
命令行中使用java命令来运行测试程序加载jni动态库时,为了确保能够找到动态库,可以将动态库以及其依赖库所在的目录添加到临时环境变量Path,命令: set PATH=%PATH%;C:\Directory1\;C:\Directory2\;C:\Directory3\
二、查看JDK架构
命令1. java -version
,如下图,可以看出jdk版本是17.0.10, 架构是64位
命令2. java -d32 -version
或者java -d64 -version
哪个运行成功就是哪个j架构。(但是我这两个命令都出现了error,不知道为啥)
那么目前可知JDK和系统架构都是64位的,动态库也是编译的64位,但是保险起见,还是要通过命令实际看一下动态库的位数。
三、查看动态库的架构
如图,打开VS的命令行工具, 也可以直接去dumpbin.exe所在的目录下面打开cmd, dumpbin 通常位于 Visual Studio 的安装目录下的 VC\Tools\MSVC\<版本号>\bin\Hostx64\x64
或 Hostx64\x86 文件夹中
然后,输入命令 dumpbin /hearders a.dll
,然后看下面输出内容中“machine”的部分,后面括号中"x64"表示是64位,"x86"表示32位
那么到这里可以确定我的动态库本身是没有问题的,那么问题可能就出在依赖库上。
四、查看动态库的依赖项
同样打开VS的命令行工具,使用命令:dumpbin /dependents +dll/exe文件路径
如图,可以看到这些依赖库中只有第一个是一个第三方依赖库,其余几个都是windows底层库,那么需要重点关注的就是第一个依赖库。
首先确保这个依赖库跟报错的动态库一起都加入了环境变量中能被Java找到(第一步),然后同样检查一下这个依赖库的依赖库,发现它只依赖了一些windows底层库,没什么问题,再检查一下它的架构(第三步命令),发现它竟然是32位的!!!
好好好,问题找到了,主动态库和jdk都是64位的,偏偏这个第三方依赖库是一个32位。那么现在只需要将它替换成64位的版本,问题就解决了。(鼓掌)