(原)android的JNI中使用C++的类
android的JNI代码中可以调用C++的类,但是不能直接调用,要加上一个类似于接口的java类,这个类内部调用C++的类。实际上和接口类直接调用C++中的函数差不多,只是稍微复杂了一点。
1. 写一个简单的类(一直都是用VS自动生成的类,很少自己写一个类,因而此处也是用VS生成类,然后复制到Eclipse工程的jni目录下。)该类包含4个函数:
a带参数的构造函数,用于初始化类中的变量。
b析构函数,用于释放类中的指针(数组)
c求和函数calcSum
d求平均值函数calcMean
下面的代码是VS转到JNI后编译通过的代码(VS生成的可能需要稍微修改一点)
// myMeanSum.h文件
#pragma once #include <stdio.h>
#include <stdlib.h> class myMeanSum
{
public:
myMeanSum();
~myMeanSum();
myMeanSum(int* data, int num); double calcMean();
int calcSum(); private:
int m_number;
int* databuf;
double m_mean;
int m_sum;
};
// myMeanSum.cpp文件 #include "myMeanSum.h" myMeanSum::myMeanSum()
: m_mean()
, m_sum()
, m_number()
{
databuf = new int[];
} myMeanSum::myMeanSum(int* data, int num)
: m_mean()
, m_sum()
, m_number()
{
m_number = num;
databuf = new int[m_number];
memcpy(databuf, data, sizeof(int)*m_number);
} myMeanSum::~myMeanSum()
{
if (databuf!=NULL)
{
delete[] databuf;
databuf = NULL;
}
} double myMeanSum::calcMean()
{
m_sum = calcSum();
return m_sum / 1.0 / m_number; // / 1.0用来保证int类型自动转换成double类型。
} int myMeanSum::calcSum()
{
m_sum = ;
for (int i = ; i < m_number; i++)
{
m_sum += databuf[i];
}
return m_sum;
}
2. 在Eclipse中创建新的android工程testClass。
3. 添加JNI文件AndroidClass.cpp。
4. 添加接口文件AndroidClass.java。
5. 在AndroidClass.java中添加long类型的指针,用于存储类的地址private long ptr_;
6. 在AndroidClass.java添加AndroidClass的构造函数:
public AndroidClass(int[] data, int num)
{
ptr_=AndroidClassGen(data, num);
}
7. 在AndroidClass.java添加6中函数调用的函数接口:
private native long AndroidClassGen(int[] data, int num);
8. 在AndroidClass.cpp添加7中调用class的接口函数。
JNIEXPORT jlong JNICALL Java_com_example_testclass_AndroidClass_AndroidClassGen
(JNIEnv *env, jobject obj, jintArray data, jint num)
{
jint *iAdata = env->GetIntArrayElements(data, ); jlong ptr= reinterpret_cast<jlong>(new myMeanSum(reinterpret_cast<int*>(iAdata), num)); env->ReleaseIntArrayElements(data, iAdata, ); return ptr;
}
9. 在AndroidClass.java添加释放内存的函数AndroidClassFree,感觉这两个函数名字不一定需要相同(相同没有错误,不相同没测试)。
public void AndroidClassFree()
{
AndroidClassFree(ptr_);
}
private native void AndroidClassFree(long ptr);
10. 在AndroidClass.cpp添加9中调用class的接口函数。
JNIEXPORT void JNICALL Java_com_example_testclass_AndroidClass_AndroidClassFree
(JNIEnv *, jobject, jlong ptr)
{
if(reinterpret_cast<myMeanSum*>(ptr))
{
delete reinterpret_cast<myMeanSum*>(ptr);
ptr = ;
}
}
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中添加如下简单的测试代码:
int number = ;
int* data = new int[number];
for (int i = ; i < number; i++)
{
data[i] = i;
}
myMeanSum temp(data, number);
printf("%d\n", temp.calcSum());
printf("%f\n", temp.calcMean());
输出为
4.500000
2. 在Eclipse的MainActivity.java的onCreate中添加如下测试代码:
int number = ;
int[] data = new int[number];
for (int i = ; i < number; i++)
{
data[i] = i;
} AndroidClass test=new AndroidClass(data,number);
System.out.println("test-----"+test.calcSum());
System.out.println("test-----"+test.calcMean());
test.AndroidClassFree();
结果如下:

证明程序正确。
3. 为了证明class中的析构函数正确被调用,databuf申请的内存能正常释放,填写如下测试代码:
int number = *;
int[] data = new int[number];
for (int i = ; i < number; i++)
{
data[i] = i;
} for(int i=;i<;i++)
{
AndroidClass test=new AndroidClass(data,number);
System.out.println("test-----"+i+" "+test.calcSum());
System.out.println("test-----"+i+" "+test.calcMean());
test.AndroidClassFree();
}
程序执行完没有出错。证明析构函数能正确的执行,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 Pro] Android studio jni中调用Log输出调试信息
reference to : http://www.linuxidc.com/Linux/2014-02/96341.htm Android 开发中,java 可以方便的使用调试信息Log.i, Lo ...
- (原)android的alertdialog中加入edittext但是不弹出软键盘等问题的解决与原因
摘要:alertdialog中加入edittext但是不弹出软键盘等问题网上有很多不管用的解决方案, 本文意在给出更有效的解决办法,并初步探究其原因 正文 在对话框中插入文本框是十分常见的需求 通常我 ...
- (原+转)Eclipse中Android调用OpenCv
大部分都是参考下面的网址,如果感觉看起来不舒服,可以直接查看原网址.最后遇到了一点问题: Description Resource Path Location Type E:/~\cod ...
- android的JNI 、 NDK 学习!
转载的! Java Native Interface (JNI)标准是java平台的一部分,它允许Java代码和其他语言写的代码进行交互.JNI 是本地编程接口,它使得在 Java 虚拟机 (VM) ...
- android的JNI标准 android的NDK
转载的! Java Native Interface (JNI)标准是java平台的一部分,它允许Java代码和其他语言写的代码进行交互.JNI 是本地编程接口,它使得在 Java 虚拟机 (VM) ...
- [原] Android 自定义View步骤
例子如下:Android 自定义View 密码框 例子 1 良好的自定义View 易用,标准,开放. 一个设计良好的自定义view和其他设计良好的类很像.封装了某个具有易用性接口的功能组合,这些功能能 ...
- ZT ANDROID jni 中的事件回调机制JNIenv的使用 2012-09-10 12:53:01
ANDROID jni 中的事件回调机制JNIenv的使用 2012-09-10 12:53:01 分类: 嵌入式 android framework 里java调用native,使用JNI机制,ja ...
- Base64编解码Android和ios的例子,补充JNI中的例子
1.在Android中java层提供了工具类:android.util.Base64; 里面都是静态方法,方便直接使用: 使用方法如下: // Base64 编码: byte [] encode = ...
- android学习笔记----JNI中的c控制java
面向对象的底层实现 java作为面向对象高级语言,可对现实世界进行建模.和面向过程不同的是面向对象软件的编写不是流程的堆积,而是对业务逻辑的多视角分解和分类.其过程大致为: 1).将知识分解 ...
随机推荐
- UVA 221 - Urban Elevations(离散化)!!!!!!
题意:给出一张俯视图.给出N个建筑物的左下标,长度,宽度,高度.现在求,从南面看,能看到那些建筑? Sample Input 14 160 0 30 60 30 125 0 32 28 60 95 0 ...
- hdu 1085 Holding Bin-Laden Captive!
Problem Description We all know that Bin-Laden is a notorious terrorist, and he has disappeared for ...
- (原)ubuntu上安装dlib
转载请注明出处: http://www.cnblogs.com/darkknightzh/p/5652791.html 参考网址: http://stackoverflow.com/questions ...
- Android网络连接的两种方法:apache client和httpurlconnection的比较
另见http://blog.csdn.net/mingli198611/article/details/8766585 在官方blog中,android工程师谈到了如何去选择apache client ...
- javascript 执行顺序详解
JavaScript是一种描述 型脚本语言,它不同于java或C#等编译性语言,它不需要进行编译成中间语言,而是由浏览器进行动态地解析与执行.如果你不能理解javaScript 语言的运行机制,或者简 ...
- [C++程序设计]指针数组和指向指针的指针
指针数组的概念 一维指针数组的定义形式为 类型名*数组名[数组长度]; 例如 int *p[4]; 可以用指针数组中各个元素分别指向若干个字符串,使字符串处理更加方便灵活
- 学习http的一个网站
http://www.blogjava.net/zjusuyong/articles/304788.html
- javascrit字符串截取
昨天遇见一个问题就是一个地址后面加参数第一次是需要添加参数,以后每次点击按钮的时候是替换如果不进行处理的话如果页面不刷新,地址会不断的添加越来越长,所以
- POJ 1190 生日蛋糕(DFS)
生日蛋糕 Time Limit: 1000MSMemory Limit: 10000KB64bit IO Format: %I64d & %I64u Submit Status Descrip ...
- POJ 1195 Mobile phones (二维树状数组或线段树)
偶然发现这题还没A掉............速速解决了............. 树状数组和线段树比较下,线段树是在是太冗余了,以后能用树状数组还是尽量用......... #include < ...