当前位置:操作系统 > 安卓/Android >>

android jni——basic Types, Strings and Arrays

 学习一门新的编程语言,数据类型是最基本的东西,这里我们讲述下jni中的数据类型。

在JNI中把数据类型分为3类:

primitive type:int float char

reference type:class instances arrays

string type

在 HelloWorld中我们打印出HelloWorld等字样,我们没有传入任何参数,这里先给出一个例子,我们在java端传入字符串,然后看在jni中时如何做处理的。

这个例子跟之前的Helloworld差不多,稍作修改,我们在java端传入参数,

新建一个类,专门用来封转jni的method:


[java]
 package com.android.jni; 
 
public class Prompt { 
    public native String getLine(String prompt); 
    static { 
        System.loadLibrary("MyJNI"); 
    } 
 

在主activity中调用:


[java]
//调用原生函数得到字符串str 
Prompt pmt = new Prompt(); 
String str=pmt.getLine("Put in a line!"); 
//吐出message 
Toast.makeText(mContext, str, Toast.LENGTH_SHORT).show(); 
         

我们调用了Prompt中的getLine方法。

然后看下C中的代码:


[cpp]
jstring 
Java_com_android_jni_Prompt_getLine(JNIEnv* env,jobject jobj,jstring prompt) 

    char buf[128]; 
    const jbyte *str; 
    str = (*env)->GetStringUTFChars(env,prompt,NULL); 
    if(str == NULL) 
        return NULL; 
    __android_log_print(ANDROID_LOG_INFO,"-JNI-","%s",str); 
    (*env)->ReleaseStringUTFChars(env,prompt,str); 
    sprintf(buf,"From C + %s",str); 
    return (*env)->NewStringUTF(env,buf); 

getLine函数呼叫了JNI的功能函数GetStringUFTChars来读取我们传入的prompt字符串(java端)。GetStringUFTChars函数进入JNIEnv 结构指针,把java中的UTF-8字符类型转变成C中的Unicode sequence,转换成jstring 参考来使用。

最后在释放str的时候不要忘记检查str是否为空,因为GetStringUFTChars函数可能会调用失败(outofmenory)。

当原生代码把传进来的UTF-8类型字符串之后应该立即释放内存调用ReleaseStringUTFChars。

调用NewStringUTF函数来构建新的字符串return给java代码。

在模拟器中运行,当我们点击按钮的时候会出现字符串,“From C + 。。。”

 

 

\


调用成功。

---------------------------------------------------------------------------------

下面我们来进入数组,先看下面的数组定义:

int[] iarr;

float[] farr;

Object oarr;

int[][] arr2;

iarr和farr是数据数组,但是oarr和arr2是对象数组。

下面举个例子进入数据数组:

先看下我们要实现的,在java代码中:

 

 

[cpp]
 //调用原生函数得到字符串str 
//Prompt pmt = new Prompt(); 
//String str=pmt.getLine("Put in a line!"); 
int arr[] = new int[10]; 
for(int i=0;i<10;i++) 
    arr[i]=i; 
int sum = IntArray.sumArray(arr); 
//吐出message 
Toast.makeText(mContext, "sum = "+sum, Toast.LENGTH_SHORT).show(); 

 

封装动态库function:


[cpp]
 package com.android.jni; 
 
public class IntArray { 
    public native static int sumArray(int[] arr); 
 
    static { 
        System.loadLibrary("IntArray"); 
    } 

 

定义一个数组,然后调用jni中的function来对数组进行操作,这边在java代码中传进去的是一个整形的数组。

-----------------------------------------------------------------------------------------------

我们来看下在jni中是如何处理的:


[cpp]
jint 
Java_com_android_jni_Native_sumArray(JNIEnv* env,jobject jobj,jintArray arr) 

    jint buf[10]; 
    jint i, sum = 0; 
    (*env)->GetIntArrayRegion(env,arr,0,10,buf); 
    for(i=0;i<10;i++) 
        sum += buf[i]; 
    return sum; 

 


这里调用了GetIntArrayRegion函数来把传进来的arr数组中的数据都拷贝进C,该函数第三个参数是索引的开始值,第四个参数是被拷贝的数。

JNI也可以使用Get/Release<Type>ArrayElements 函数来使原生代码直接拥有数组的指针。


[cpp]

Java_com_android_jni_Native_sumArray(JNIEnv* env,jobject jobj,jintArray arr) 

//  jint buf[10]; 
    jint *carr; 
    jint i, sum = 0; 
//  (*env)->GetIntArrayRegion(env,arr,0,10,buf); 
    carr = (*env)->GetIntArrayElements(env,arr,NULL); 
    if(carr == NULL) 
        return 0; 
    for(i=0;i<10;i++) 
        sum += carr[i]; 
    (*env)->ReleaseIntArrayElements(env,arr,carr,0); 
    return sum; 

运行模拟器:

 \
 


----------------------------------------------------------------------------------------

下面我们来看下jni中对对象数组的处理。

看下原生函数的声明


[cpp]
 public static native int[][] intitInt2DArray(int size);  

下面是jni中的实现


[cpp] v
 jobjectArray 
Java_com_android_jni_Native_initInt2DArray(JNIEnv *env, 
        jclass cls,int size) 

    jobjectArray result; 
    int i; 
    jclass intArrCls = (*env)->FindClass(env, "[I"); 
    if (intArrCls == NULL) { 
        return NULL; /* exception thrown */ 
    } 
    result = (*env)->NewObjectArray(env, size, intArrCls,NULL); 
    if (result == NULL) { 
        return NULL; /* out of memory error thrown */ 
    } 
    for (i = 0; i < size; i++) { 
        jint tmp[256]; /* make sure it is large enough! */ 
        int j; 
        jintArray iarr = (*env)->NewIntArray(env, size); 
        if (iarr == NULL) { 
            return NULL; /* out o

补充:移动开发 , Android ,
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,