本文参考《较详细的介绍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小记的更多相关文章

  1. JNI 回调小记

    javah在eclipse中设置参数:location(javah.exe的位置)working dir(${project_loc}/src) -classpath .;./classes -d $ ...

  2. java jni 调用c语言函数

    今日在hibernate源代码中遇到了native关键词,甚是陌生,就查了点资料,对native是什么东西有了那么一点了解,并做一小记. native关键字说明其修饰的方法是一个原生态方法,方法对应的 ...

  3. android studio 使用 jni 编译 opencv 完整实例 之 图像边缘检测!从此在andrid中自由使用 图像匹配、识别、检测

    目录: 1,过程感慨: 2,运行环境: 3,准备工作: 4,编译 .so 5,遇到的关键问题及其解决方法 6,实现效果截图. (原创:转载声明出处:http://www.cnblogs.com/lin ...

  4. 【走过巨坑】android studio对于jni调用及运行闪退无法加载库的问题解决方案

    相信很多小伙伴都在android开发中遇到调用jni的各种巨坑,因为我们不得不在很多地方用到第三方库so文件,然而第三方官方通常都只会给出ADT环境下的集成方式,而谷歌亲儿子android studi ...

  5. [原]Paste.deploy 与 WSGI, keystone 小记

    Paste.deploy 与 WSGI, keystone 小记 名词解释: Paste.deploy 是一个WSGI工具包,用于更方便的管理WSGI应用, 可以通过配置文件,将WSGI应用加载起来. ...

  6. Android游戏开发实践(1)之NDK与JNI开发03

    Android游戏开发实践(1)之NDK与JNI开发03 前面已经分享了两篇有关Android平台NDK与JNI开发相关的内容.以下列举前面两篇的链接地址,感兴趣的可以再回顾下.那么,这篇继续这个小专 ...

  7. JNI 备注

    本文记录一个基础的JNI例子及过程中遇到的问题解决. 1.定义一个JAVA类如下: package jnidemo01; public class JniHello { public native v ...

  8. Android游戏开发实践(1)之NDK与JNI开发01

    Android游戏开发实践(1)之NDK与JNI开发01 NDK是Native Developement Kit的缩写,顾名思义,NDK是Google提供的一套原生Java代码与本地C/C++代码&q ...

  9. Android游戏开发实践(1)之NDK与JNI开发02

    Android游戏开发实践(1)之NDK与JNI开发02 承接上篇Android游戏开发实践(1)之NDK与JNI开发01分享完JNI的基础和简要开发流程之后,再来分享下在Android环境下的JNI ...

随机推荐

  1. 76-Java安装Eclipse并创建第一个HelloWorld.md

    76-Java安装Eclipse并创建第一个HelloWorld.md 首先确定已经安装Java系统环境,若未安装,请参考博客Java环境windows搭建 访问Eclipse官网 下载完成直接发送快 ...

  2. 分布式存储ceph---openstack对接ceph存储后端(4)

    ceph对接openstack环境 一.使用RBD方式提供存储,如下数据: 1.image:保存glance中的image 2.volume存储:保存cinder的volume:保存创建虚拟机时选择创 ...

  3. linux中级之HAProxy基础配置

    一.haproxy简介 HAProxy是一款提供高可用性.负载均衡以及基于TCP(第四层)和HTTP(第七层)应用的代理软件,HAProxy是完全免费的.借助HAProxy可以快速并且可靠的提供基于T ...

  4. Linux中级之ansible概念及hoc命令行调用模式

    一.Ansible简介 ansible是新出现的开源的自动化运维工具,基于Python开发,集合了众多运维工具(puppet.cfengine.chef.func.fabric)的优点,实现了批量系统 ...

  5. 关于步进电机驱动板,tb6560

    参考的,淘宝上买来的步进电机S曲线驱动方法,发现 他程序输出的PWM波形全是方波,  占空比为50% 而且他 修改这两个数来输出波形,所以 我打算参考这个来写一个驱动 TIMX_CNT中放置的是当前计 ...

  6. lua type 获取 类型

    lua中的类型作一小记 print(type("Hello world")) --> string print(type(10.4*3)) --> number pri ...

  7. 在浏览器上运行 VS Code——GitHub 热点速览 v.21.22

    作者:HelloGitHub-小鱼干 和小程序类似,如果平时开发所用到的软件也能运行在浏览器中,"用完即走"岂不妙哉?code-server 便是一个让人在浏览器运行 VS Cod ...

  8. Hadoop系列番外篇之一文搞懂Hadoop RPC框架及细节实现

    @ 目录 Hadoop RPC 框架解析 1.Hadoop RPC框架概述 1.1 RPC框架特点 1.2 Hadoop RPC框架 2.Java基础知识回顾 2.1 Java反射机制与动态代理 2. ...

  9. GO学习-(37) 使用Air实现Go程序实时热重载

    使用Air实现Go程序实时热重载 今天我们要介绍一个神器--Air能够实时监听项目的代码文件,在代码发生变更之后自动重新编译并执行,大大提高gin框架项目的开发效率. 为什么需要实时加载? 之前使用P ...

  10. celery异步任务体系笔记

    1.异步框架示意图 2.celery 官方文档 http://docs.celeryproject.org/en/latest/index.html 3.启动celery的命令 启动 sender 自 ...