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 ...
随机推荐
- xpath定位中starts-with、contains、text()的用法
starts-with 顾名思义,匹配一个属性开始位置的关键字 contains 匹配一个属性值中包含的字符串 text() 匹配的是显示文本信息,此处也可以用来做定位用 eg //input[sta ...
- 大数据 什么是 ETL
ETL 概念 ETL 这个术语来源于数据仓库,ETL 指的是将业务系统的数据经过抽取.清洗转换之后加载到数据仓库的过程.ETL 的目的是将企业中的分散.零乱.标准不统一的数据整合到一起,为企业的决策提 ...
- Socket编程——(转载)
我们深谙信息交流的价值,那网络中进程之间如何通信,如我们每天打开浏览器浏览网页时,浏览器的进程怎么与web服务器通信的?当你用QQ聊天时,QQ进程怎么与服务器或你好友所在的QQ进程通信?这些都得靠so ...
- 1.3Linux 终端命令格式
Linux 终端命令格式 目标 了解终端命令格式 知道如何查阅终端命令帮助信息 01. 终端命令格式 bashcommand [-options] [parameter] 说明: command:命令 ...
- Git 系列教程(14)- 远程分支
远程分支 远程引用是对远程仓库的引用(指针),包括分支.标签等等 你可以通过 git ls-remote <remote> 来显式地获得远程引用的完整列表 polo@B-J5D1MD6R- ...
- ffmpeg安装之mac安装
转发自白狼栈:查看原文 关于ffmpeg的安装,有的人可能要折腾很久,甚至折腾一个礼拜,究其原因,基本都是编译安装惹的祸. 我们提供4种安装方式,最复杂的莫过于centos7上的编译安装. ffmpe ...
- 【六】K8s-Pod 水平自动扩缩实践(简称HPA)
一.概述 Pod 水平自动扩缩(Horizontal Pod Autoscaler)简称 HPA,HPA 可以根据 CPU 利用率进行自动伸缩 Pod 副本数量,除了 CPU 利用率,也可以基于其他应 ...
- 项目中添加lib依赖
Project Structure-->Artifacts
- ISP算法高水平分析(上)
ISP算法高水平分析(上) 一.ISP基本框架及算法介绍 ISP是Image Signal Processor的缩写,全称是影像处理器.在相机成像的整个环节中,它负责接收感光元件(Sensor)的原始 ...
- 前台JS遍历Table的所有单元格数据内容
在日常开发过程中为了减少与后台服务器的交互次数,大部分的功能都会放到前台使用JS来完成. 例如:一个表中有ID(FOCUS_SEQ)和Name(COLUMNCTRL)两个字段,其中ID是自定义连续增长 ...