jni中基本类型数组的传递方法(无需拷贝数据)
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
JNI中基本类型数组的传递方法(无需拷贝数据!!!)
0、先来看一下主要用到哪些函数:
C 代码GetIntArrayElements();//貌似得到的是副本,要拷贝数据ReleaseIntArrayElements();//对应上面的函数的释放资源的函数env->GetPrimitiveArrayCritical();//貌似
得到的是指向原数据的指针
env->ReleasePrimitiveArrayCritical();////对应上面的函数
的释放资源的函数
官方文档:
/javase/7/docs/technotes/guides/jni/ spec/functions.html#wp17440
JNI函数的中译本(貌似没看到GetPrimitiveArrayCritical()):/qinjuning下面正式开始:1、不知道如
何设置JNI环境的先看这里:
/blog/13281362、Java端程序:
Java端:
Java代码package tests; import java.util.Arrays; public class TestJNIArray
{ static{ System.loadLibrary("TestJNIArra y"); } public static native void
addOne(int[] ints);//数组元素1 public static native void addOne(double[] ints);//数组元素1,为了测试,C 中循环了5次public static native int[] getNewArray(int size,int initValue);//生成初始值为initValue的数组,数组长度为size public static void main(String[] args) throws InterruptedException { int n=20;
final int[] a=new int[n]; for (int i = 0; i < a.length; i ) { a[i]=i; }
if(n<50)System.out.println(Arrays.toString(a));
addOne(a);
if(n<50)System.out.println(Arrays.toString(a));
final double d[]=new double[n]; for (int i = 0; i <
d.length; i ) { d[i]=i; }
//addOne(d);
if(n<50)System.out.println(Arrays.toString(d));
new Thread(new Runnable()
{ @Override
public void run()
{ addOne(d);
} }).start(); for (int i = 0; i < 200; i ) { Thread.sleep(20);
System.out.println(Arrays.toString(d));
if(d[d.length-1]-d[0]!=n-1)System.out.println("检测到C 端
更新数据中");//看看能否找到在C 更新数组时Java端又读取数据的情况}
int[] b=getNewArray(2, 9);
System.out.println(Arrays.toString(b));
int[] c=getNewArray(0, 9);
System.out.println(Arrays.toString(c)); }
} 3、C 端程序:
C 代码#include "tests_TestJNIArray.h" #include
<windows.h> #include <time.h> #include
<iostream> #include <string> class
Timer{ private: clock_t time; public:
Timer(){ time=clock(); } clock_t getElapsedTime(){ return clock()-time; } clock_t getElapsedTimeAndRestart(){ clock_t tmp=time; time=clock(); return
time-tmp; } void
restart(){ time=clock(); } int getCLOCKS_PER_SEC(){ return
CLOCKS_PER_SEC; } }; JNIEXPORT void JNICALL Java_tests_TestJNIArray_addOne___3I( JNIEnv * env, jclass, jintArray intArray) { jboolean b;
Timer timer; jint*
pint=env->GetIntArrayElements(intArray,&b);//获取指针!!第二个参数可为NULL std::string
str=b?"true":"false"; long
t=timer.getElapsedTimeAndRestart();
std::cout<<"GetIntArrayElements()耗时:
"<<t<<"\t为副本?"<<str<<std::endl;//很悲剧,自己得到的是副本(copy了一份,速度慢啊)jsize size=env->GetArrayLength(intArray); for (int i=0; i<size; i ) pint[i] =1;
env->ReleaseIntArrayElements(intArray,pint,0);//释放
~~~ // 对于最后一个参数(如果指针指向的数组为副本时,否则该参数不起作用) // 0 copy back the content and free the elems buffer //
JNI_COMMIT copy back the content but do not free the elems buffer // JNI_ABORT free