转载于:https://www.cnblogs.com/GDUT/p/3806771.html

由于JNI调用C和调用C++差不多,而且C++中可以混合写C代码,所以这里主要是写关于JNI调用C++的部分。

  • 一般步骤:

  1. 先是写普通的Java类,其中包括本地方法调用。 
  2. 然后编译这个Java类,调用javah命令,生成.h头文件
  3. 接着,就是实现头文件中的函数;实现过程中有点比较麻烦,要知道JNI中JAVA和C/C++的类型转换,比如数组类型的转换,基本类型的转换等,最好是看文档,或者网上找相关资料。

源代码链接:http://files.cnblogs.com/GDUT/jni-demo.rar

  • JNI的调用效果图:

  • 下面是调用JNI的具体过程:

1.  普通Java类(包含测试方法):MyJNI.java

 1 public class MyJNI {2 3     //加载动态链接库4     static {5         System.out.println("开始加载动态链接库");6         System.loadLibrary("MyJNI");7         System.out.println("动态链接库加载完毕。");8     }9
10     public native void go();
11
12     public native void run();
13
14     public native String getName();
15
16     public native int[] sort(int[] array);
17
18     //测试
19     public static void main(String[] args) {
20         MyJNI jni = new MyJNI();
21         int[] array = {5, 3, 6, 35, 74, 8}, sortedArray;
22
23         jni.run();
24         jni.go();
25         jni.getName();
26         sortedArray = jni.sort(array);
27         //由于这是本地方法调用,这里的数组和平常的数组的引用不太一样。
28
29         for(int i=0; i<sortedArray.length; i++){
30             System.out.print(sortedArray[i] + "\t");
31         }
32
33     }
34 }

2.  由Java类编译后生成的C++头文件:MyJNI.h

 1 /* DO NOT EDIT THIS FILE - it is machine generated */2 #include <jni.h>3 /* Header for class MyJNI */4 5 #ifndef _Included_MyJNI6 #define _Included_MyJNI7 #ifdef __cplusplus8 extern "C" {9 #endif
10 /*
11  * Class:     MyJNI
12  * Method:    go
13  * Signature: ()V
14  */
15 JNIEXPORT void JNICALL Java_MyJNI_go
16   (JNIEnv *, jobject);
17
18 /*
19  * Class:     MyJNI
20  * Method:    run
21  * Signature: ()V
22  */
23 JNIEXPORT void JNICALL Java_MyJNI_run
24   (JNIEnv *, jobject);
25
26 /*
27  * Class:     MyJNI
28  * Method:    getName
29  * Signature: ()Ljava/lang/String;
30  */
31 JNIEXPORT jstring JNICALL Java_MyJNI_getName
32   (JNIEnv *, jobject);
33
34 /*
35  * Class:     MyJNI
36  * Method:    sort
37  * Signature: ([I)[I
38  */
39 JNIEXPORT jintArray JNICALL Java_MyJNI_sort
40   (JNIEnv *, jobject, jintArray);
41
42 #ifdef __cplusplus
43 }
44 #endif
45 #endif

3.  需要调用的C++函数的相关文件:MyJNIImpl.cpp

 1 #include <jni.h>2 #include "MyJNI.h"3 #include <stdio.h>4 5 6 /*7  * Class:     MyJNI8  * Method:    go9  * Signature: ()V
10  */
11 JNIEXPORT void JNICALL Java_MyJNI_go
12   (JNIEnv * env, jobject jobj){
13
14     printf("I am going....\n");
15 }
16
17 /*
18  * Class:     MyJNI
19  * Method:    run
20  * Signature: ()V
21  */
22 JNIEXPORT void JNICALL Java_MyJNI_run
23   (JNIEnv * env, jobject jobj){
24
25     printf("I am running....\n");
26 }
27
28 /*
29  * Class:     MyJNI
30  * Method:    getName
31  * Signature: ()Ljava/lang/String;
32  */
33 JNIEXPORT jstring JNICALL Java_MyJNI_getName
34   (JNIEnv * env, jobject job){
35
36    printf("I am GDUTtiantian, go with me.\n");
37    //将字符串转化为jstring类型
38    //jstring就是对应java的String类型
39    jstring p = env->NewStringUTF("GDUTtiantian");
40    return p;
41 }
42
43 /*
44  * Class:     MyJNI
45  * Method:    sort
46  * Signature: ([I)[I
47  */
48 JNIEXPORT jintArray JNICALL Java_MyJNI_sort
49   (JNIEnv * env, jobject jobj, jintArray array){
50
51 jint* arr;//定义一个整形指针
52     int sum=0;
53     //对于整形数组的处理,主要有GetIntArrayElements与GetIntArrayRegion
54     //第一种方法
55     arr = env->GetIntArrayElements(array, NULL);//得到一个指向原始数据类型内容的指针
56     jint length = env->GetArrayLength(array);//得到数组的长度
57
58     for(int i=0; i<length; i++){
59         for(int j=i+1; j<length; j++){
60             if(arr[i] > arr[j]){
61                 jint temp = arr[i];
62                 arr[i] = arr[j];
63                 arr[j] = temp;
64             }
65         }
66     }
67
68
69     for(int i=0; i<length; i++){
70         printf("%d ", arr[i]);
71     }
72
73     printf("\n排序完成\n");
74
75     jintArray javaArray = env->NewIntArray(length);
76     env->SetIntArrayRegion(javaArray, 0, length, arr);
77
78     return javaArray;//返回排序后的数组
79 }

编译之后,生成一个动态链接库文件:MyJNI.dll

在Java类中就是通过加载这个库文件,调用其中的相关函数。

调用的相关命令:

  • javac *.java
  • javah MyJNI
  • set JAVA_HOME=D:\SoftwareDeveloping\jdk32bit_1.6
  • g++ -Wl,--add-stdcall-alias -I"%JAVA_HOME%\include" -I"%JAVA_HOME%\include\win32" -shared -o MyJNI.dll MyJNIImpl.cpp
  • java MyJNI
  • 在操作过程中可能会出现的异常:

  1.  第一个异常 

 1 C:\Users\Administrator\Desktop>java HelloJNI2 Exception in thread "main" java.lang.UnsupportedClassVersionError: HelloJNI : Unsupported major.minor version 51.03         at java.lang.ClassLoader.defineClass1(Native Method)4         at java.lang.ClassLoader.defineClassCond(ClassLoader.java:631)5         at java.lang.ClassLoader.defineClass(ClassLoader.java:615)6         at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:141)7         at java.net.URLClassLoader.defineClass(URLClassLoader.java:283)8         at java.net.URLClassLoader.access$000(URLClassLoader.java:58)9         at java.net.URLClassLoader$1.run(URLClassLoader.java:197)
10         at java.security.AccessController.doPrivileged(Native Method)
11         at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
12         at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
13         at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
14         at java.lang.ClassLoader.loadClass(ClassLoader.java:247)
15 Could not find the main class: HelloJNI.  Program will exit.

这个是JAVA虚拟机的版本低于编译器的问题,如果你用一个编译编译之后,然后把.class文件移动到另一个环境下执行,可能会出现这个问题。

  2.     第二个异常

 1 C:\Users\Administrator\Desktop>javac *.java2 3 C:\Users\Administrator\Desktop>java HelloJNI4 Exception in thread "main" java.lang.UnsatisfiedLinkError: C:\Users\Administrator\Desktop\hello.dll: Can't load IA 32-bit .dll on a AMD 64-bit platform5         at java.lang.ClassLoader$NativeLibrary.load(Native Method)6         at java.lang.ClassLoader.loadLibrary0(ClassLoader.java:1807)7         at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1732)8         at java.lang.Runtime.loadLibrary0(Runtime.java:823)9         at java.lang.System.loadLibrary(System.java:1028)
10         at HelloJNI.<clinit>(HelloJNI.java:3)
11 Could not find the main class: HelloJNI.  Program will exit.

动态链接库.dll是32位,而JVM是64位,不匹配;可以安装一个32位的JVM;或者在64位环境下重新编译一个新的.dll文件。

3.    第三个异常

 1 C:\Users\Administrator\Desktop\jni>g++ -Wl,--add-stdcall-alias -I"%JAVA_HOME%\include" -I"%JAVA_HOME%\include\win32" -shared -o MyJNI.dll MyJNIImpl.cpp2 In file included from MyJNIImpl.cpp:1:3 MyJNI.h:2:17: jni.h: No such file or directory4 In file included from MyJNIImpl.cpp:1:5 MyJNI.h:15: error: expected constructor, destructor, or type conversion before "void"6 MyJNI.h:15: error: expected `,' or `;' before "void"7 MyJNI.h:23: error: expected constructor, destructor, or type conversion before "void"8 MyJNI.h:23: error: expected `,' or `;' before "void"9 MyJNI.h:31: error: `JNIEXPORT' does not name a type
10 MyJNI.h:39: error: `JNIEXPORT' does not name a type
11 MyJNIImpl.cpp:10: error: expected constructor, destructor, or type conversion before "void"
12 MyJNIImpl.cpp:10: error: expected `,' or `;' before "void"
13 MyJNIImpl.cpp:21: error: expected constructor, destructor, or type conversion before "void"
14 MyJNIImpl.cpp:21: error: expected `,' or `;' before "void"
15 MyJNIImpl.cpp:32: error: `JNIEXPORT' does not name a type
16 MyJNIImpl.cpp:47: error: `JNIEXPORT' does not name a type

这个报错主要是找不到jni.h文件,一般的原因:JAVA_HOME的路径有问题,注意这个路径是安装路径。用命令设置下,如果设置还是报这个错误,那么就到环境变量那里修改。

参考资料:http://www3.ntu.edu.sg/home/ehchua/programming/java/JavaNativeInterface.html

JNI类型转换:http://www.cnblogs.com/lgydqy/archive/2012/02/28/2371592.html

函数

Java 数组类型

本地类型

GetBooleanArrayElements

jbooleanArray

jboolean

GetByteArrayElements

jbyteArray

jbyte

GetCharArrayElements

jcharArray

jchar

GetShortArrayElements

jshortArray

jshort

GetIntArrayElements

jintArray

jint

GetLongArrayElements

jlongArray

jlong

GetFloatArrayElements

jfloatArray

jfloat

GetDoubleArrayElements

jdoubleArray

jdouble

转(JAVA的JNI调用)相关推荐

  1. Java通过JNI调用C++动态链接库dll,并打在jar包内 ——JNA-JNI(一)

    Java通过JNI调用C++动态链接库dll,并打在jar包内--JNA-JNI(一) 系列文章: Java通过JNI调用C++动态链接库dll,并打在jar包内 --JNA-JNI(一) Java使 ...

  2. JAVA通过JNI调用C++动态链接库CLL(二)

    简介 使用Visual Studio 2017新建c++动态链接库dll项目 编写JniDemo.h中getName实现并生成DLL 编写JniDemo.h在JniDemo.c实现getName方法 ...

  3. JAVA通过JNI调用C++动态链接库CLL(一)

    简介 使用eclipse新建JAVA项目并生成.h头文件 新建项目JniDemo 新建测试类JniTest并声明一个native的方法 使用Javah命令生成native方法的声明的C/C++头文件 ...

  4. Java通过-jni调用c语言

    Java通过-jni调用c语言 一.编写JAVA程序 二.编译h头文件 三.编写C方法实现 四.生成对象文件 五.生成动态链接库 六.执行 一.编写JAVA程序 public class TestNa ...

  5. java在主程序修改函数输出,Java通过JNI调用CUDA

    --NG 这段时间因为工作需要,要用到在java中调用cuda程序,但是令人蛋疼的是网上这方面的资料几乎没有,所以只好我自己摸索.我的想法是通过java的JNI接口调用cuda,但是很明显正常情况下是 ...

  6. Java通过JNI调用C++的DLL库

    2019独角兽企业重金招聘Python工程师标准>>> Java通过JNI实现调用C++程序 好久没碰JNI这个东西了,刚工作的时候自己写过点东西,这么些年很少用到,最近一个项目又用 ...

  7. java通过jni调用虚拟游戏控制器vjoy

    这几天打算做个游戏方向盘之类的,找到了vjoy,安装后会虚拟出1到16个游戏控制器,每个游戏控制器最多支持8轴128键,还有力反馈什么的,提供有skd可以编写client端控制这些游戏控制器的各个轴. ...

  8. 用java的jni调用C语言的API,实现带图形界面的一元稀疏多项式计算器

    实现步骤: 1) 完成Java代码,编写好Java调用类. 2) 编译你的Java类. 3) 用javah生成编译好的class文件对应的C/C++ 函数的头文件. 4) 实现头文件中的函数原型,编写 ...

  9. Java利用JNI调用c++代码简易例子演示

    点击打开链接 (提取码:8676) 一.首先简单交代一下两个问题: 1.什么是JNI                - - -     JNI的全名为Java Native Interface(Jav ...

最新文章

  1. 线程的生命周期其实没有我们想象的那么简单!!
  2. UA MATH567 高维统计 专题1 Supervised PCA Regression概述
  3. 洛谷P1040 加分二叉树运用区间DP(动态规划)求解
  4. 【新功能,新插件】-全新来袭,CSDN浏览器助手这一款无广告干净界面插件你值得拥有!
  5. 【深度】阿里巴巴万级规模 K8s 集群全局高可用体系之美
  6. 使用 .toLocaleString() 轻松实现多国语言价格数字格式化
  7. STL源码剖析 关联式容器 树 红黑树、二叉搜索树、平衡二叉搜索树
  8. 飞秋(FeiQ)2012版择日发布
  9. 修手机时创意被剽窃,男子向苹果索赔7万亿!是认真的吗?
  10. P1828 香甜的黄油 Sweet Butter (spfa)
  11. java jframe 设置背景图片_JAVA怎样设置JFrame的背景图片呢?谁能教教我怎么弄背景图片...
  12. Extjs4.x (MVC)Controller中refs以及Ext.ComponentQuery解析
  13. python语言的主网址-Python爬取网址中多个页面的信息
  14. Extjs基础入门视频教程
  15. 鸟哥的Linux私房菜基础学习篇(第四版)
  16. C语言炫酷的文件操作
  17. 樱(桜) - 堀江由衣 (日语-中文-罗马)
  18. 未来IT行业前景如何?
  19. Material Design实战
  20. IDEA使用database时,连接MySQL后schemas不显示数据库名的情况

热门文章

  1. ui设计是干啥的: ui设计师主要是做什么的呢
  2. 问题记录:Ubuntu中source运行.sh shell脚本报错:command not found 未找到命令
  3. 明翰英语教学系列之方法篇
  4. 108.【RabbitsMQ】
  5. brpc源码解析(二)—— brpc收到请求的处理过程
  6. 初级计算机信息处理员笔试题,初级信息处理技术员计算机系统基础知识考试卷模拟考试^题...
  7. Application应用程序
  8. 计算机小学数学辅助教学缺点及对策 论文,小学数学第二学段图形与几何领域的作业设计研究...
  9. 云计算基础知识培训讲义
  10. Apollo使用篇 - Apollo客户端的使用