(原)android的JNI中使用C++的类
android的JNI代码中可以调用C++的类,但是不能直接调用,要加上一个类似于接口的java类,这个类内部调用C++的类。实际上和接口类直接调用C++中的函数差不多,只是稍微复杂了一点。
1. 写一个简单的类(一直都是用VS自动生成的类,很少自己写一个类,因而此处也是用VS生成类,然后复制到Eclipse工程的jni目录下。)该类包含4个函数:
a带参数的构造函数,用于初始化类中的变量。
b析构函数,用于释放类中的指针(数组)
c求和函数calcSum
d求平均值函数calcMean
下面的代码是VS转到JNI后编译通过的代码(VS生成的可能需要稍微修改一点)
1 // myMeanSum.h文件 2 #pragma once 3 4 #include <stdio.h> 5 #include <stdlib.h> 6 7 class myMeanSum 8 { 9 public: 10 myMeanSum(); 11 ~myMeanSum(); 12 myMeanSum(int* data, int num); 13 14 double calcMean(); 15 int calcSum(); 16 17 private: 18 int m_number; 19 int* databuf; 20 double m_mean; 21 int m_sum; 22 };
1 // myMeanSum.cpp文件 2 3 #include "myMeanSum.h" 4 5 myMeanSum::myMeanSum() 6 : m_mean(0) 7 , m_sum(0) 8 , m_number(0) 9 { 10 databuf = new int[10]; 11 } 12 13 myMeanSum::myMeanSum(int* data, int num) 14 : m_mean(0) 15 , m_sum(0) 16 , m_number(0) 17 { 18 m_number = num; 19 databuf = new int[m_number]; 20 memcpy(databuf, data, sizeof(int)*m_number); 21 } 22 23 24 myMeanSum::~myMeanSum() 25 { 26 if (databuf!=NULL) 27 { 28 delete[] databuf; 29 databuf = NULL; 30 } 31 } 32 33 34 double myMeanSum::calcMean() 35 { 36 m_sum = calcSum(); 37 return m_sum / 1.0 / m_number; // / 1.0用来保证int类型自动转换成double类型。 38 } 39 40 41 int myMeanSum::calcSum() 42 { 43 m_sum = 0; 44 for (int i = 0; i < m_number; i++) 45 { 46 m_sum += databuf[i]; 47 } 48 return m_sum; 49 }
2. 在Eclipse中创建新的android工程testClass。
3. 添加JNI文件AndroidClass.cpp。
4. 添加接口文件AndroidClass.java。
5. 在AndroidClass.java中添加long类型的指针,用于存储类的地址private long ptr_;
6. 在AndroidClass.java添加AndroidClass的构造函数:
1 public AndroidClass(int[] data, int num) 2 { 3 ptr_=AndroidClassGen(data, num); 4 }
7. 在AndroidClass.java添加6中函数调用的函数接口:
private native long AndroidClassGen(int[] data, int num);
8. 在AndroidClass.cpp添加7中调用class的接口函数。
1 JNIEXPORT jlong JNICALL Java_com_example_testclass_AndroidClass_AndroidClassGen 2 (JNIEnv *env, jobject obj, jintArray data, jint num) 3 { 4 jint *iAdata = env->GetIntArrayElements(data, 0); 5 6 jlong ptr= reinterpret_cast<jlong>(new myMeanSum(reinterpret_cast<int*>(iAdata), num)); 7 8 env->ReleaseIntArrayElements(data, iAdata, 0); 9 10 return ptr; 11 }
9. 在AndroidClass.java添加释放内存的函数AndroidClassFree,感觉这两个函数名字不一定需要相同(相同没有错误,不相同没测试)。
1 public void AndroidClassFree() 2 { 3 AndroidClassFree(ptr_); 4 }
private native void AndroidClassFree(long ptr);
10. 在AndroidClass.cpp添加9中调用class的接口函数。
1 JNIEXPORT void JNICALL Java_com_example_testclass_AndroidClass_AndroidClassFree 2 (JNIEnv *, jobject, jlong ptr) 3 { 4 if(reinterpret_cast<myMeanSum*>(ptr)) 5 { 6 delete reinterpret_cast<myMeanSum*>(ptr); 7 ptr = 0; 8 } 9 }
11. 在android.mk中添加需要编译的C++类的源文件(默认是LOCAL_SRC_FILES := AndroidClass.cpp):
LOCAL_SRC_FILES := AndroidClass.cpp myMeanSum.cpp
12. 分别添加其他的代码,此处略去,详见工程:
https://github.com/darkknightzh/testClass
说明:AndroidClassGetPtr程序不使用,如果需要在外部的AndroidClass定义的对象A使用对象B,则使用这个函数传入 B的指针。
测试步骤:
1. 在VS中添加如下简单的测试代码:
1 int number = 10; 2 int* data = new int[number]; 3 for (int i = 0; i < number; i++) 4 { 5 data[i] = i; 6 } 7 myMeanSum temp(data, number); 8 printf("%d\n", temp.calcSum()); 9 printf("%f\n", temp.calcMean());
输出为
45 4.500000
2. 在Eclipse的MainActivity.java的onCreate中添加如下测试代码:
1 int number = 10; 2 int[] data = new int[number]; 3 for (int i = 0; i < number; i++) 4 { 5 data[i] = i; 6 } 7 8 AndroidClass test=new AndroidClass(data,number); 9 System.out.println("test-----"+test.calcSum()); 10 System.out.println("test-----"+test.calcMean()); 11 test.AndroidClassFree();
结果如下:
证明程序正确。
3. 为了证明class中的析构函数正确被调用,databuf申请的内存能正常释放,填写如下测试代码:
1 int number = 1000*1000; 2 int[] data = new int[number]; 3 for (int i = 0; i < number; i++) 4 { 5 data[i] = i; 6 } 7 8 for(int i=0;i<1000;i++) 9 { 10 AndroidClass test=new AndroidClass(data,number); 11 System.out.println("test-----"+i+" "+test.calcSum()); 12 System.out.println("test-----"+i+" "+test.calcMean()); 13 test.AndroidClassFree(); 14 }
程序执行完没有出错。证明析构函数能正确的执行,databuf申请的内存能正常释放。
4. 注释掉test.AndroidClassFree();后,程序跑到128次的时候崩溃,之后继续从0开始跑。证明AndroidClassFree函数正确的执行了析构函数。
5. 跑上面3的代码,但是myMeanSum类中的析构函数里面的代码全部注释掉,程序跑到128次后依旧崩溃,证明AndroidClassFree函数正确的执行了析构函数。
ps,上面程序只是一个简单的例子,可能有不完善的地方,同时代码写得也不是很好。
参考网址(貌似不能愉快的访问,感谢原作者,以及不能愉快的访问的搜索引擎):
http://stylishtoupee.blogspot.jp/2011/07/jni-example-with-class-instantiation-c.html
(原)android的JNI中使用C++的类相关推荐
- 【Android】JNI调用(完整版)
原文出处:http://blog.csdn.net/kangyaping/article/details/6584027#t0 Chap1:JNI完全手册... 3 Chap2:JNI-百度百科... ...
- Android与JNI(一)
2019独角兽企业重金招聘Python工程师标准>>> Eddy_He 博客园 首页 新随笔 联系 订阅 管理 随笔- 55 文章- 0 评论- 3 Android与JNI(一) ...
- android 源码中的单例,Android源码中的一种单例实现
单例模式的实现方式有懒汉,饿汉,双重校验锁,枚举,内部类等等,写法就不全部列举了.Android源码中有一个单例辅助类/frameworks/base/core/java/android/util/S ...
- android studio 自动提示jni代码,如何将JNI(C/C++本机代码)添加到现有的Android Studio项目中...
从现有项目中执行以下步骤: 1.修改build.gradle(模块应用程序)看起来像这样(很多变化!): apply plugin: 'com.android.model.application' m ...
- 【Android 安装包优化】使用 lib7zr.so 动态库处理压缩文件 ( jni 中 main 函数声明 | 命令行处理 | jni 调用 lib7zr.so 函数库处理压缩文件完整代码 )
文章目录 一.JNI 中 main 函数声明 二.命令字符串切割并传入 main 函数 三.完整代码示例 1.完整 jni 代码 2.完整 java 代码 3.执行结果 四.参考资料 前置博客 : [ ...
- android+jni+构造函数,在JNI中调用构造函数失败Android
我想从我的JNI Android代码调用构造函数;但不知何故,它失败,以下例外.. 我相信我失去了一些非常小的东西;但我无法弄清楚......任何人都可以请指出?在JNI中调用构造函数失败Androi ...
- android studio 导入模块SDK 以及该模块中继承application的类与原工程继承application的类存在冲突 解决方法
android studio 导入模块SDK 以及该模块中继承application的类与原工程继承application的类存在冲突 解决方法 导入某修改后的海康视频SDK(老师给的),并修改相关文 ...
- android jni 中实现 LOG 输出调试
android jni 中实现 LOG 输出调试 在jni 文件夹下 android.mk文件中 添加 LOCAL_LDLIBS += -L$(SYSTEM)/usr/lib -llog 在jni中添 ...
- Android For JNI(二)——C语言中的数据类型,输出,输入函数以及操作内存地址,内存修改器
Android For JNI(二)--C语言中的数据类型,输出,输入函数以及操作内存地址,内存修改器 当我们把Hello World写完之后,我们就可以迈入C的大门了,今天就来讲讲基本的一些数据类型 ...
最新文章
- 虚拟机+可信+云计算
- 009_JavaScript语句、表达式和代码块
- 数据结构和算法解:第九章 算法设计技巧
- linux网络配置、测试及故障诊断方法和工具三
- 鼠标控制方向java代码_java鼠标操控小程序
- dagger2记录篇
- R语言观察日志(part18)--.C和.Call
- 实时监听输入框值变化的完美方案:oninput onpropertychange
- @requestparam @param @pathvariable @requestbody的区别
- 深入浅出理解HOG特征---梯度方向直方图
- django class类即视图类添加装饰器的几种方法
- TURBOMAIL邮件服务器—挽救错误邮件
- 【转】Python之装饰器
- yuv420sp转jpg
- 使用安卓模拟器+Xposed+JustTrustMe+burp suite抓取app的https流量
- go,go语言编辑器安装,git安装,即vscode三个插件的安装
- 2017会考计算机知识点,【高考备考】2017高二化学会考知识点汇总高中化学会考知识点...
- 机器学习服务文本识别能力演进,大幅提升识别准确率
- 苏州大学 计算机网络,苏州大学计算机网络与通信期末考试卷-20210517192500.docx-原创力文档...
- 按Backspace键删除时,会出现^H