C++ 通过jni生成库供JAVA调用(下)--C++生成库并JAVA可以调用(windows)
2017-08-29 22:34
489 查看
C++ 通过jni生成库供JAVA调用(下)–C++生成库并JAVA可以调用(windows)
项目上 JAVA通过C++库去调用硬件设备,需要用C++封装库,然后JAVA调用C++的库,这里描述JAVA调用C++库的过程。这里实现C++生成库可让JAVA通过JNI去调用
编译环境:VS2015; eclipse/(使用命令行也操作可行,eclipse不熟悉,然后开始没有使用它)
语言: C++, JAVA
这个过程中遇到了一些坑,JAVA也是只会写个hello world ,然后在java调用库的时候会出现一些问题。
使用notepad++建立个.java文件,输出所需要实现的一些接口
使用文本来实现.java文件
在java文件里面声明在C++里面需要实现的接口或者已经存在的接口,数据类型需要适当的转换。在D:\jni\java_jni\java_jni下建立个文件jniCppSDK.java
并输入一下内容
package java_jni; public class jniCppSDK { public native void sayHello(); public native int sum(int a, int b); public native int max(int a, int b, int c); static { System.loadLibrary("jniCppSDK"); } public static void main(String[] args) { jniCppSDK test = new jniCppSDK(); test.sayHello(); System.out.println(test.sum(10, 21)); 4000 System.out.println(test.max(10, 12, 20)); System.out.println("hello JAVA"); } }
或者使用eclipse来实现.java文件
该步骤和上个步骤的目的是一样的打开eclipse – File – New – Java Project( 保存路径为
D:\jni\java_jni\java_jni_eclipse,工程名称:
java_jni_eclipse) – Next – Finish
在src处右键 New – Package ,Name 更改为
java_jni
在java_jni包处右键 New – Class , Class名字设置为
jniCppSDK
在jniCppSDK.java文件里面可以看到内容:
package java_jni; public class jniCppSDK { }
将之前代码添加到该Class里面
package java_jni; public class jniCppSDK { public native void sayHello(); public native int sum(int a, int b); public native int max(int a, int b, int c); static { System.loadLibrary("jniCppSDK"); } public static void main(String[] args) { jniCppSDK test = new jniCppSDK(); test.sayHello(); System.out.println(test.sum(10, 21)); System.out.println(test.max(10, 12, 20)); System.out.println("hello JAVA"); } }
利用javah 生成jni头文件
C++代码实现头文件这些接口,然后可以生成JAVA可以调用的库了对使用notepad++之类的文本编辑器,进行操作
在jniCppSDK .java文件路径下,按住shift键+鼠标右键,点击在此处打开Powershell窗口,输出javac jniCppSDK.java,可以看到文件夹里面多出了jniCppSDK.class文件
由于.java文件使用
package java_jni;声明,需要在java文件的父路径上进行操作,在shell里面输出
cd ../, 路径会回到
D:\jni\java_jni里面,然后输入
javah java_jni.jniCppSDK,来生成jni头文件,然后会在该路径下出现
java_jni_jniCppSDK.h文件
如果java文件里面没有package的声明的话,直接在java文件所在路径下
javah java_jni.jniCppSDK就可以了,因为java文件里面有
package java_jni;所以在生成头文件的时候需要在java文件的上层目录下进行操作
对使用eclipse的java文件操作
进入到eclipse工程里面,到D:\jni\java_jni\java_jni_eclipse\src\java_jni路径下,然后进入Powershell路径下’javac jniCppSDK.java’
然后
cd ../,到上级目录下,运行
javah java_jni.jniCppSDK,然后该路径下会出现
java_jni_jniCppSDK.h文件,
上面两种情况下生成 jni头文件,比较两种状况下得到的jni头文件,两者完全一样。
通过jni头文件和C++里面的程序进行对接
VS工程环境搭建
在D:\jni\java_jni里面,创建win32控制台的工程,工程名称为jniCppSDK,程序类型选择DLL,空项目。
将
java_jni_jniCppSDK.h头文件添加到工程头文件里面,将
testSDK.cpp工程源文件(可以自己新建个源文件)
// testSDK.cpp : 定义 DLL 应用程序的导出函数。 // #include <iostream> #include "java_jni_jniCppSDK.h" void helloSDK() { std::cout << "hello sdk" << std::endl; } int mySum(int a, int b) { return (a + b); } int myMax(int a, int b, int c) { int max = a; if (max < b) max = b; if (max < c) max = c; return max; }
此时编译的话,会出现无法打开 源 文件 “jni.h”的情况,需要将java的jni路径添加到附加包含目录配置属性 – C/C++ – 附加包含目录 添加
C:\Program Files\Java\jdk1.8.0_144\include\;C:\Program Files\Java\jdk1.8.0_144\include\win32,
注意:x86平台和x64平台的设置,可能是目录添加到x86里面,缺以x64平台运行的,所有还是会找不到
jni.h文件,所以我两个平台都添加了附加包含目录。
添加Source.def文件,输入以下内容,否则的话,链接不到方法。
LIBRARY "jniCppSDK" EXPORTS Java_java_1jni_jniCppSDK_sayHello @1 Java_java_1jni_jniCppSDK_sum @2 Java_java_1jni_jniCppSDK_max @3
编写代码
testSDK.cpp与生成的jni头文件接口对接,完成之后的代码:// testSDK.cpp : 定义 DLL 应用程序的导出函数。 // #include <iostream> #include "java_jni_jniCppSDK.h" void helloSDK() { std::cout << "hello sdk" << std::endl; } int mySum(int a, int b) { return (a + b); } int myMax(int a, int b, int c) { int max = a; if (max < b) max = b; if (max < c) max = c; return max; } /* * Class: java_jni_jniCppSDK * Method: sayHello * Signature: ()V */ JNIEXPORT void JNICALL Java_java_1jni_jniCppSDK_sayHello (JNIEnv *, jobject) { helloSDK(); } /* * Class: java_jni_jniCppSDK * Method: sum * Signature: (II)I */ JNIEXPORT jint JNICALL Java_java_1jni_jniCppSDK_sum (JNIEnv * env , jobject obj, jint a, jint b) { return (jint)(mySum((int)a, (int)b)); } /* * Class: java_jni_jniCppSDK * Method: max * Signature: (III)I */ JNIEXPORT jint JNICALL Java_java_1jni_jniCppSDK_max (JNIEnv * env, jobject obj, jint a, jint b, jint c) { return (jint)(myMax((int)a, (int)b, (int)c)); }
编译运行,生成dll文件。
将dll文件放到D:\jni\java_jni
路径下,命令行下运行java程序
D:\jni\java_jni> java java_jni.jniCppSDK
运行结果:
hello sdk 31 20 hello JAVA
将dll文件丢到eclipse工程路径下运行
运行结果:hello sdk 31 20 hello JAVA
java调用C++库成功
附上测试源码:相关文章推荐
- C++ 通过jni生成库供JAVA调用(上) (C++之间的调用)
- windows7下,Java中利用JNI调用c++生成的动态库的使用步骤
- windows7下,Java中利用JNI调用c++生成的动态库的使用步骤
- 通过JNI实现Java和C++的相互调用(转)
- 通过JNI实现Java和C++的相互调用(转)
- 通过JNI实现Java和C++的相互调用(转)
- 通过JNI实现Java和C++的相互调用(转)
- 通过JNI实现Java和C++的相互调用(转)
- 通过JNI实现Java和C++的相互调用(转)
- 通过JNI实现Java和C++的相互调用
- 通过JNI实现Java和C++的相互调用(转)
- ubuntu下,C/C++通过JNI调用 JAVA类
- 通过JNI实现Java和C++的相互调用
- 通过JNI实现Java和C++的相互调用(转)
- 通过JNI实现Java和C++的相互调用(转)
- 通过JNI实现Java和C++的相互调用(转)
- 通过JNI实现Java和C++的相互调用(转)
- 通过JNI实现Java和C++的相互调用(转)
- 通过JNI实现Java和C++的相互调用(转)
- 通过JNI实现Java和C++的相互调用(转)