【问题描述】某一天突然在项目遇到一个问题,要求用Java调用C++的方法,网上找了不少方法,踩了比较多坑才调用成功,于是写这篇文章让大家避免入坑啦~
注意,我用的是MacOS,不是Windows。
Step1. 编写test.java
【说明】
方法用native声明。
test.java在Image包下。
System.load是加载动态链接库文件,在Step5有说明。
Step2. 编译test.java -> test.class
具体方法:打开终端,进入test.java文件目录,执行$ javac test.java
【说明】生成的test.class在Image包下。
Step3. 生成.h头文件 -> Image_test.h
具体方法:打开终端,进入test.java文件的上一层目录,执行$ javah Image.test, Image是包名,test指的是刚刚生成的test.class
【说明】此时,会生成一个名叫Image_test.h的头文件,把此头文件移动到Image目录下,也就是和test.java、test.class文件放在一起。
Step4. 根据Image_test.h编写c++
具体方法:用Xcode新建一个c++文件,命名为helloWorld.cpp。
【说明】此处编写的c++文件有所讲究
1. cpp的头文件需要参考Step3生成的.h头文件编写。.h头文件引入了<jni.h>,<Image_test>,所以在cpp文件中就要include这两个头文件。
2. 参考.h头文件的函数声明,复制到cpp文件中,把参数稍作更改。在cpp中实现此方法,这里做一个简单的输出HelloWorld。
3.把cpp文件放入Image文件夹。即test.java、test.class 、Image_test.h、helloWorld.cpp在同一个目录Image
Step5. 生成动态链接库(libNativeCode.jnilib)
生成之前,先做预备工作。打开Finder,按“Shift+Command+g”,输入路径:“/Library/Java/JavaVirtualMachines/jdk1.8.0_40.jdk/Contents/Home/include”,把darwin的jni_md.h复制一份到include目录,此动作需要管理员密码。
【生成动态链接库】打开终端:进入Image目录,执行 $ g++ -shared -I /Library/Java/JavaVirtualMachines/jdk1.8.0_40.jdk/Contents/Home/include helloWorld.cpp -o libNativeCode.jnilib
【说明】
1. -l 是 i 的大写,不是 L 的小写。
2. helloWorld.cpp就是刚刚编写的C++文件。
3. libNativeCode.jnilib是动态链接库的命名,命名规范必须是lib开头,后缀必须是jnilib。
4. 执行命令后生成libNativeCode.jnilib,放在Image目录下,即test.java、test.class 、Image_test.h、helloWorld.cpp、libNativeCode.jnilib 都在同一个目录Image中。
Step6. 右键运行test.java,就可以打印HelloWord。大功告成。
总结一下,其实步骤就是
1. 编写test.java
2. 编译test.java -> test.class
3. javah命令生成.h文件
4. 按照.h文件函数命名格式编写c++文件
5. 生成动态链接库