JNI小记
本文参考《较详细的介绍JNI》一文,并添加了一些方法,代码已经过测试,留待日后工作使用。关于JNI的HelloWorld的例子,就不赘述了。
java代码:
1 package com.chnic.service;
2
3 import com.chnic.bean.Order;
4
5 public class Business {
6 static{
7 System.loadLibrary("FruitFactory");
8 }
9
10 public Business(){
11
12 }
13
14 public native double getPrice(String name);
15 public native Order getOrder(String name, int amount);
16 public native Order getRamdomOrder();
17 public static native void analyzeOrder(Order order);
18
19 public native void showArray(int []nums);
20
21 public native int[] getIntArray();
22
23 public native String[] getStringArray(String[] ss);
24
25 public native void test2DStringArray(String[][] ss);
26
27 public void notification(){
28 System.out.println("Got a notification.");
29 }
30
31 public static void notificationByStatic(){
32 System.out.println("Got a notification in a static method.");
33 }
34
35 public static void main(String...args){
36 Business bus = new Business();
37 System.out.println("price:"+bus.getPrice("Apple"));
38 System.out.println("-------------------------");
39
40 System.out.println("price:"+bus.getPrice("Pear"));
41 System.out.println("-------------------------");
42
43 System.out.println(bus.getOrder("Apple",23));
44 System.out.println("-------------------------");
45
46 System.out.println(bus.getRamdomOrder());
47 System.out.println("-------------------------");
48
49 Order order = new Order();
50 order.setName("orange");
51 Business.analyzeOrder(order);
52 System.out.println("-------------------------");
53
54 int[]ia={1,2,3,4};
55 bus.showArray(ia);
56 System.out.println("-------------------------");
57
58 int[] iaa = bus.getIntArray();
59 for(int i:iaa){
60 System.out.println(i);
61 }
62 System.out.println("-------------------------");
63
64 String[]abc= {"aa","bb","cc","dd"};
65 bus.getStringArray(abc);
66 System.out.println("-------------------------");
67
68 String []abcd = bus.getStringArray(abc);
69 for(String s:abcd){
70 System.out.println(s);
71 }
72 System.out.println("-------------------------");
73
74 String[][]test = {{"一行1号","一行二号","一行三号"},{"二行一号","二行二号","二行三号"}};
75 bus.test2DStringArray(test);
76 System.out.println("-------------------------");
77 }
78 }
1 package com.chnic.bean;
2
3 public class Order {
4
5 private String name = "Fruit";
6 private double price;
7 private int amount = 30;
8
9 public Order(){
10
11 }
12
13 public int getAmount() {
14 return amount;
15 }
16
17 public void setAmount(int amount) {
18 this.amount = amount;
19 }
20
21 public String getName() {
22 return name;
23 }
24
25 public void setName(String name) {
26 this.name = name;
27 }
28
29 public double getPrice() {
30 return price;
31 }
32
33 public void setPrice(double price) {
34 this.price = price;
35 }
36
37 public String toString(){
38 return "name is "+name+",price is "+price+",amount is "+amount+".";
39 }
40 }
生成的com_chnic_service_Business.h头文件内容如下:
1 /* DO NOT EDIT THIS FILE - it is machine generated */
2 #include <jni.h>
3 /* Header for class com_chnic_service_Business */
4
5 #ifndef _Included_com_chnic_service_Business
6 #define _Included_com_chnic_service_Business
7 #ifdef __cplusplus
8 extern "C" {
9 #endif
10 /*
11 * Class: com_chnic_service_Business
12 * Method: getPrice
13 * Signature: (Ljava/lang/String;)D
14 */
15 JNIEXPORT jdouble JNICALL Java_com_chnic_service_Business_getPrice
16 (JNIEnv *, jobject, jstring);
17
18 /*
19 * Class: com_chnic_service_Business
20 * Method: getOrder
21 * Signature: (Ljava/lang/String;I)Lcom/chnic/bean/Order;
22 */
23 JNIEXPORT jobject JNICALL Java_com_chnic_service_Business_getOrder
24 (JNIEnv *, jobject, jstring, jint);
25
26 /*
27 * Class: com_chnic_service_Business
28 * Method: getRamdomOrder
29 * Signature: ()Lcom/chnic/bean/Order;
30 */
31 JNIEXPORT jobject JNICALL Java_com_chnic_service_Business_getRamdomOrder
32 (JNIEnv *, jobject);
33
34 /*
35 * Class: com_chnic_service_Business
36 * Method: analyzeOrder
37 * Signature: (Lcom/chnic/bean/Order;)V
38 */
39 JNIEXPORT void JNICALL Java_com_chnic_service_Business_analyzeOrder
40 (JNIEnv *, jclass, jobject);
41
42 /*
43 * Class: com_chnic_service_Business
44 * Method: showArray
45 * Signature: ([I)V
46 */
47 JNIEXPORT void JNICALL Java_com_chnic_service_Business_showArray
48 (JNIEnv *, jobject, jintArray);
49
50 /*
51 * Class: com_chnic_service_Business
52 * Method: getIntArray
53 * Signature: ()[I
54 */
55 JNIEXPORT jintArray JNICALL Java_com_chnic_service_Business_getIntArray
56 (JNIEnv *, jobject);
57
58 /*
59 * Class: com_chnic_service_Business
60 * Method: getStringArray
61 * Signature: ([Ljava/lang/String;)[Ljava/lang/String;
62 */
63 JNIEXPORT jobjectArray JNICALL Java_com_chnic_service_Business_getStringArray
64 (JNIEnv *, jobject, jobjectArray);
65
66 /*
67 * Class: com_chnic_service_Business
68 * Method: test2DStringArray
69 * Signature: ([[Ljava/lang/String;)V
70 */
71 JNIEXPORT void JNICALL Java_com_chnic_service_Business_test2DStringArray
72 (JNIEnv *, jobject, jobjectArray);
73
74 #ifdef __cplusplus
75 }
76 #endif
77 #endif
编写的CPP实现文件(文件名随意),内容如下:
1 #include <iostream.h>
2 #include <string.h>
3 #include "com_chnic_service_Business.h"
4
5 jobject getInstance(JNIEnv* env, jclass obj_class);
6 /*
7 * Class: com_chnic_service_Business
8 * Method: getPrice
9 * Signature: (Ljava/lang/String;)D
10 * 传递string参数,返回double值
11 */
12 JNIEXPORT jdouble JNICALL Java_com_chnic_service_Business_getPrice(JNIEnv* env,
13 jobject obj,
14 jstring name)
15 {
16 const char* pname = env->GetStringUTFChars(name, NULL);
17 cout << "Before release: " << pname << endl;
18
19 if (strcmp(pname, "Apple") == 0)
20 {
21 env->ReleaseStringUTFChars(name, pname);
22 cout << "After release: " << pname << endl;
23 return 1.2;
24 }
25 else
26 {
27 env->ReleaseStringUTFChars(name, pname);
28 cout << "After release: " << pname << endl;
29 return 2.1;
30 }
31 }
32
33 /*
34 * Class: com_chnic_service_Business
35 * Method: getOrder
36 * Signature: (Ljava/lang/String;I)Lcom/chnic/bean/Order;
37 * 传递string、int参数,回调java类中的方法,并且返回一个java对象
38 */
39 JNIEXPORT jobject JNICALL Java_com_chnic_service_Business_getOrder(JNIEnv* env,
40 jobject obj,
41 jstring name,
42 jint amount)
43 {
44 jclass order_class = env->FindClass("com/chnic/bean/Order");
45 jobject order = getInstance(env, order_class);
46
47 jmethodID setName_method = env->GetMethodID(order_class, "setName", "(Ljava/lang/String;)V");
48 env->CallVoidMethod(order, setName_method, name);
49
50 jmethodID setAmount_method = env->GetMethodID(order_class, "setAmount", "(I)V");
51 env->CallVoidMethod(order, setAmount_method, amount);
52
53 return order;
54 }
55
56 /*
57 * Class: com_chnic_service_Business
58 * Method: getRamdomOrder
59 * Signature: ()Lcom/chnic/bean/Order;
60 * 无参方法,在C++中构造一个java对象返回
61 */
62 JNIEXPORT jobject JNICALL Java_com_chnic_service_Business_getRamdomOrder(JNIEnv* env,
63 jobject obj)
64 {
65 jclass business_class = env->GetObjectClass(obj);
66 jobject business_obj = getInstance(env, business_class);
67
68 jmethodID notification_method = env->GetMethodID(business_class, "notification", "()V");
69 env->CallVoidMethod(obj, notification_method);
70
71 jclass order_class = env->FindClass("com/chnic/bean/Order");
72 jobject order = getInstance(env, order_class);
73 jfieldID amount_field = env->GetFieldID(order_class, "amount", "I");
74 jint amount = env->GetIntField(order, amount_field);
75 cout << "amount: " << amount << endl;
76 return order;
77 }
78
79
80 /*
81 * Class: com_chnic_service_Business
82 * Method: analyzeOrder
83 * Signature: (Lcom/chnic/bean/Order;)V
84 * java中的静态方法,在C++中的实现,传递的参数是java对象,无返回值
85 */
86 JNIEXPORT void JNICALL Java_com_chnic_service_Business_analyzeOrder (JNIEnv* env,
87 jclass cls,
88 jobject obj)
89 {
90 jclass order_class = env->GetObjectClass(obj);
91 jmethodID getName_method = env->GetMethodID(order_class, "getName", "()Ljava/lang/String;");
92 jstring name_str = static_cast<jstring>(env->CallObjectMethod(obj, getName_method));
93 const char* pname = env->GetStringUTFChars(name_str, NULL);
94
95 cout << "Name in Java_com_chnic_service_Business_analyzeOrder: " << pname << endl;
96
97
98 jmethodID notification_method_static = env->GetStaticMethodID(cls, "notificationByStatic", "()V");
99 env->CallStaticVoidMethod(cls, notification_method_static);
100
101 }
102
103 /*
104 * 根据类,构造对应的对象返回
105 */
106 jobject getInstance(JNIEnv* env, jclass obj_class)
107 {
108 jmethodID construction_id = env->GetMethodID(obj_class, "<init>", "()V");
109 jobject obj = env->NewObject(obj_class, construction_id);
110 return obj;
111 }
112
113 /*
114 * Class: com_chnic_service_Business
115 * Method: showArray
116 * Signature: ([I)V
117 * 传递字符串数组,在C++中使用
118 */
119 JNIEXPORT void JNICALL Java_com_chnic_service_Business_showArray
120 (JNIEnv* env, jobject job, jintArray jia)
121 {
122 jint* nums;
123 nums = env->GetIntArrayElements(jia,NULL);
124
125 jint length = env->GetArrayLength(jia);
126 cout<<"length:"<<length<<endl;
127 int i;
128 for(i=0;i<length;i++)
129 {
130 cout<<nums[i]<<endl;
131 }
132 }
133
134 /*
135 * Class: com_chnic_service_Business
136 * Method: getIntArray
137 * Signature: ()[I
138 * 返回整形数组
139 */
140 JNIEXPORT jintArray JNICALL Java_com_chnic_service_Business_getIntArray
141 (JNIEnv *env, jobject job)
142 {
143 jsize col=10;
144 jint temp[10]={1,2,3,4,5,6,7,8,9,10};
145
146 jintArray iarr = env->NewIntArray(col);
147 env->SetIntArrayRegion(iarr, 0, col, temp);
148 return iarr;
149 }
150
151 /*
152 * Class: com_chnic_service_Business
153 * Method: getStringArray
154 * Signature: ([Ljava/lang/String;)[Ljava/lang/String;
155 * 传递一个字符串数组,并且重新构造一个字符串数组,并返回
156 */
157 JNIEXPORT jobjectArray JNICALL Java_com_chnic_service_Business_getStringArray
158 (JNIEnv* env, jobject job, jobjectArray joa)
159 {
160 //打印传递进来的字符串数组
161 jsize si = env->GetArrayLength(joa);
162 //cout<<si<<endl;
163 int i;
164 for(i=0;i<si;i++)
165 {
166 jstring str = (jstring)(env)->GetObjectArrayElement(joa, i);
167 //cout<<str<<endl;
168 const char* pname = env->GetStringUTFChars(str, NULL);
169 cout<<pname<<endl;
170 }
171 //构造新的字符串数组
172 jstring s1=env->NewStringUTF("123");
173 jstring s2=env->NewStringUTF("456");
174 jstring s3=env->NewStringUTF("789");
175 jstring ss[3]={s1,s2,s3};
176
177
178 jobjectArray swArray = env->NewObjectArray(3,env->FindClass("java/lang/String"), env->NewStringUTF(""));
179 //SetObjectArrayElement刷新数组元素内容
180 for(i = 0; i < 3; i++)
181 env->SetObjectArrayElement(swArray, i, ss[i]) ;
182 return swArray;
183 }
184
185 /**
186 * java传递二维字符串
187 *
188 */
189 JNIEXPORT void JNICALL Java_com_chnic_service_Business_test2DStringArray
190 (JNIEnv *env, jobject obj, jobjectArray array)
191 {
192 int size = env->GetArrayLength(array);
193 for (int i = 0; i < size; i++) {
194 jobjectArray myarray =(jobjectArray) (env->GetObjectArrayElement(array, i));
195 int length = env->GetArrayLength(myarray);
196 cout<<"length: "<<length<<endl;
197 for (int j = 0; j < length; j++) {
198 jstring string = (jstring)(env->GetObjectArrayElement(myarray, j));
199 const char * chars = env->GetStringUTFChars(string, 0);
200 cout<<chars<<" ";
201 env->ReleaseStringUTFChars(string, chars);
202 }
203 cout<<endl;
204 }
205 }
生成动态链接库后,运行java的main方法,控制台打印信息如下:
Before release: Apple
After release: V
price:1.2
-------------------------
Before release: Pear
After release: X
price:2.1
-------------------------
name is Apple,price is 0.0,amount is 23.
-------------------------
Got a notification.
amount: 30
name is Fruit,price is 0.0,amount is 30.
-------------------------
Name in Java_com_chnic_service_Business_analyzeOrder: orange
Got a notification in a static method.
-------------------------
length:4
1
2
3
4
-------------------------
1
2
3
4
5
6
7
8
9
10
-------------------------
aa
bb
cc
dd
-------------------------
aa
bb
cc
dd
123
456
789
-------------------------
length: 3
一行1号 一行二号 一行三号
length: 3
二行一号 二行二号 二行三号
-------------------------
备注:1、使用Win7+eclipse+VC++6.0开发
2、VC++创建Win32 Dynamic-Link Library工程
3、在java调用native方法传递中文字符串时,若java工程或java文件格式不是UTF格式,会有乱码。
JNI小记的更多相关文章
- JNI 回调小记
javah在eclipse中设置参数:location(javah.exe的位置)working dir(${project_loc}/src) -classpath .;./classes -d $ ...
- java jni 调用c语言函数
今日在hibernate源代码中遇到了native关键词,甚是陌生,就查了点资料,对native是什么东西有了那么一点了解,并做一小记. native关键字说明其修饰的方法是一个原生态方法,方法对应的 ...
- android studio 使用 jni 编译 opencv 完整实例 之 图像边缘检测!从此在andrid中自由使用 图像匹配、识别、检测
目录: 1,过程感慨: 2,运行环境: 3,准备工作: 4,编译 .so 5,遇到的关键问题及其解决方法 6,实现效果截图. (原创:转载声明出处:http://www.cnblogs.com/lin ...
- 【走过巨坑】android studio对于jni调用及运行闪退无法加载库的问题解决方案
相信很多小伙伴都在android开发中遇到调用jni的各种巨坑,因为我们不得不在很多地方用到第三方库so文件,然而第三方官方通常都只会给出ADT环境下的集成方式,而谷歌亲儿子android studi ...
- [原]Paste.deploy 与 WSGI, keystone 小记
Paste.deploy 与 WSGI, keystone 小记 名词解释: Paste.deploy 是一个WSGI工具包,用于更方便的管理WSGI应用, 可以通过配置文件,将WSGI应用加载起来. ...
- Android游戏开发实践(1)之NDK与JNI开发03
Android游戏开发实践(1)之NDK与JNI开发03 前面已经分享了两篇有关Android平台NDK与JNI开发相关的内容.以下列举前面两篇的链接地址,感兴趣的可以再回顾下.那么,这篇继续这个小专 ...
- JNI 备注
本文记录一个基础的JNI例子及过程中遇到的问题解决. 1.定义一个JAVA类如下: package jnidemo01; public class JniHello { public native v ...
- Android游戏开发实践(1)之NDK与JNI开发01
Android游戏开发实践(1)之NDK与JNI开发01 NDK是Native Developement Kit的缩写,顾名思义,NDK是Google提供的一套原生Java代码与本地C/C++代码&q ...
- Android游戏开发实践(1)之NDK与JNI开发02
Android游戏开发实践(1)之NDK与JNI开发02 承接上篇Android游戏开发实践(1)之NDK与JNI开发01分享完JNI的基础和简要开发流程之后,再来分享下在Android环境下的JNI ...
随机推荐
- Linux Socket编程-(转自吴秦(Tyler))
"一切皆Socket!" 话虽些许夸张,但是事实也是,现在的网络编程几乎都是用的socket. --有感于实际编程和开源项目研究. 我们深谙信息交流的价值,那网络中进程之间如何通信 ...
- Centos下删除文件后空间并未释放
[root@DeviceSP /]# df -h Filesystem Size Used Avail Use% Mounted on /dev/vda3 90G 82G 3.8G 96% / tmp ...
- 第七章 DevOps工具链
DevOps工具生态圈 协同开发工具 敏捷开发 可视化 加强团队沟通协作 数据分析 协同开发 持续集成工具 Jenkins 自动化编译 自动化测试 自动化部署 丰富的插件库 版本管理工具 Git 简介 ...
- 一:windows10开启虚拟化服务(也可用于部署docker提前准备)
查看虚拟化已开启: 如果未启用,则需要添加虚拟化功能:控制面板 -> 启用或关闭Windows功能 选择Hyper-V的所有功能,确定: 系统会自动搜索并安装功能.安装完毕即可. 完结,撒花~~
- TTC测距算法
TTC测距算法 输入输出接口 Input:(1)人与车(或车与车)的距离 (2)人与车(或车与车)的相对速度 Output:TTC collision time 算法介绍和设计方案 TTC是Time- ...
- 深入 Go 中各个高性能 JSON 解析库
转载请声明出处哦~,本篇文章发布于luozhiyun的博客:https://www.luozhiyun.com/archives/535 其实本来我是没打算去看 JSON 库的性能问题的,但是最近我对 ...
- Spring——Bean的作用域
Spring中Bean的作用域有五种,分别是singleton.prototype.request.session.globalSession.其中request.session.globalSess ...
- P5960 【模板】差分约束算法
题目描述 给出一组包含 $m$ 个不等式,有 $n$ 个未知数的形如: 的不等式组,求任意一组满足这个不等式组的解. 输入格式 第一行为两个正整数 $n,m$,代表未知数的数量和不等式的数量. 接下来 ...
- itools安装程序无法创建临时文件夹
做个记录: itools链接ios设备后,安装程序包时提示:无法创建临时文件夹 主要原因可能有以下几点 1.手机储存空间不足. 2.驱动组建被删除了,重启管理软件会自动跟新驱动. 解决办法:1.清除空 ...
- 面试官:如何在分布式场景下生成全局唯一 ID?
在分布式系统中,有一些场景需要使用全局唯一 ID ,可以和业务场景有关,比如支付流水号,也可以和业务场景无关,比如分库分表后需要有一个全局唯一 ID,或者用作事务版本号.分布式链路追踪等等,好的全局唯 ...