聪明出于勤奋,天才在于积累

  :: 首页 :: 博问 :: 闪存 :: 新随笔 :: :: :: 管理 ::
对于基本数据类型,在native层接口看到的参数,对应的都已经转换成native层的数据类型了,只是名字为了好对应,用 typedef 做了转换。
 
 
JAVA 的基本数据类型:
数据类型                大小               范围                                                 默认值 

byte(字节) 8    -128 - 127 0
shot(短整型) 16   -32768 - 32768 0
int(整型) 32   -2147483648-2147483648 0
long(长整型) 64   -9233372036854477808-9233372036854477808 0
float(浮点型) 32   -3.40292347E+38-3.40292347E+38 0.0f
double(双精度) 64   -1.79769313486231570E+308-1.79769313486231570E+308 0.0d
char(字符型) 16 ‘ \u0000 - u\ffff ’     ‘\u0000 ’
boolean(布尔型) 1 true/false     false
 
JAVA 数据类型对应的JNI数据类型:
 
/* "cardinal indices and sizes" */
#ifdef HAVE_INTTYPES_H
# include <inttypes.h>      /* C99 */
typedef uint8_t              jboolean;       /* unsigned 8 bits */
typedef int8_t                jbyte;          /* signed 8 bits */
typedef uint16_t             jchar;          /* unsigned 16 bits */
typedef int16_t             jshort;          /* signed 16 bits */
typedef int32_t             jint;              /* signed 32 bits */
typedef int64_t             jlong;           /* signed 64 bits */
typedef float                 jfloat;           /* 32-bit IEEE 754 */
typedef double              jdouble;        /* 64-bit IEEE 754 */
#else
typedef unsigned char       jboolean;       /* unsigned 8 bits */
typedef signed char         jbyte;          /* signed 8 bits */
typedef unsigned short    jchar;          /* unsigned 16 bits */
typedef short               jshort;         /* signed 16 bits */
typedef int                 jint;           /* signed 32 bits */
typedef long long         jlong;          /* signed 64 bits */
typedef float               jfloat;         /* 32-bit IEEE 754 */
typedef double            jdouble;        /* 64-bit IEEE 754 */
 
typedef jint              jsize;
 
 
Java的 String 和 JNI中的 JString 的关系:
#ifdef __cplusplus
/*
 * Reference types, in C++
 */
class _jobject {};
class _jstring : public _jobject {};
typedef _jobject*       jobject;
typedef _jstring*       jstring;
#else 
/* not __cplusplus */
typedef void*           jobject;
typedef jobject         jstring;
#endif 
比如java中的方法:
public native int test(String str, int i, long l, short s, double d, float f, char c);
用 javah 变成 jni的方法后成这样:
JNIEXPORT jint JNICALL Java_com_jni_test_EncodeJNI_test (JNIEnv *env, jobject objThis, jstring str, jint i, jlong l, jshort s, jdouble d, jfloat f, jchar c);
 
jlong 在 C 里面对应的 long long 类型,有64bit,输出时用 "%lld"

 

数组的传递:

public native String arrayTest(String[] strArray, int[] iArray, long[] lArray, short[] sArray, double[] dArray, float[] fArray, char[] cArray);

JNIEXPORT jstring JNICALL Java_com_jni_test_EncodeJNI_arrayTest(JNIEnv *env, jobject objThis, jobjectArray strArray, jintArray iArray, jlongArray lArray, jshortArray sArray, jdoubleArray dArray, jfloatArray fArray, jcharArray cArray);

    jbooleanArray (*NewBooleanArray)(JNIEnv*, jsize);
    jbyteArray    (*NewByteArray)(JNIEnv*, jsize);
    jcharArray    (*NewCharArray)(JNIEnv*, jsize);
    jshortArray   (*NewShortArray)(JNIEnv*, jsize);
    jintArray     (*NewIntArray)(JNIEnv*, jsize);
    jlongArray    (*NewLongArray)(JNIEnv*, jsize);
    jfloatArray   (*NewFloatArray)(JNIEnv*, jsize);
    jdoubleArray  (*NewDoubleArray)(JNIEnv*, jsize);

    jboolean*   (*GetBooleanArrayElements)(JNIEnv*, jbooleanArray, jboolean*);
    jbyte*      (*GetByteArrayElements)(JNIEnv*, jbyteArray, jboolean*);
    jchar*      (*GetCharArrayElements)(JNIEnv*, jcharArray, jboolean*);
    jshort*     (*GetShortArrayElements)(JNIEnv*, jshortArray, jboolean*);
    jint*       (*GetIntArrayElements)(JNIEnv*, jintArray, jboolean*);
    jlong*      (*GetLongArrayElements)(JNIEnv*, jlongArray, jboolean*);
    jfloat*     (*GetFloatArrayElements)(JNIEnv*, jfloatArray, jboolean*);
    jdouble*    (*GetDoubleArrayElements)(JNIEnv*, jdoubleArray, jboolean*);

 获取数组长度:     jsize   (*GetArrayLength)(JNIEnv*, jarray);

设置IntArray 的值
void SetIntArrayRegion(JNIEnv* env, jintArray array, jsize start, jsize len, const jint* buf)

 

View Code
#include "com_TestCopyPix_jni.h"
//#include other headers
JNIEXPORT jintArray JNICALL Java_com_TestCopyPix_jni_ct(JNIEnv *env, jobject obj) {
    //jdoubleArray inner = (*env)->NewDoubleArray(env, 3);
//    int i = 1;
//    jintArray  array;//定义数组对象
//    array = (*env)-> NewIntArray(env, 10);
//    for(; i<= 10; i++)
//      (*env)->SetIntArrayRegion(env, array, i-1, 1, &i);
//    /* 获取数组对象的元素个数 */
//    int len = (*env)->GetArrayLength(env, array);
//    /* 获取数组中的所有元素 */
//    jint* elems = (*env)-> GetIntArrayElements(env, array, 0);
//    for(i=0; i<len; i++)
//            printf("ELEMENT %d IS %d\n", i, elems[i]);


    int i = 1;
    int a = 20;
    int b = 200;
    jintArray  array;//定义数组对象
    array = (*env)-> NewIntArray(env, 2);
    (*env)->SetIntArrayRegion(env, array, 0, 1, &a);
    (*env)->SetIntArrayRegion(env, array, 1, 1, &b);

//        for(; i<= 2; i++)
//          (*env)->SetIntArrayRegion(env, array, i-1, 1, &i);
        /* 获取数组对象的元素个数 */
//        int len = (*env)->GetArrayLength(env, array);
//        /* 获取数组中的所有元素 */
//        jint* elems = (*env)-> GetIntArrayElements(env, array, 0);


    return array;

}
View Code
jintArray
Java_com_summer_PointerTestActivity_test( JNIEnv* env,
                                                  jobject thiz,jintArray nums)
{
    //获取传入数组的长度
    jsize len = (*env)->GetArrayLength(env, nums);
    //在java中申请一块内存  以用来将C的数组传输给java程序
    jintArray ret=(*env)->NewIntArray(env,len);

    //获取传入的数组
    jint *body = (*env)->GetIntArrayElements(env, nums, 0);
    int i;
    for(i=0;i<len;i++)
    {
        body[i] *=2;
    }

    //将C的数组拷贝给java中的数组
    (*env)->SetIntArrayRegion(env,ret,0,len,body);
    return ret;
}

 

 

 

String的处理
Java String不能直接被C++程序使用,需要先用 env->GetStringUTFChars把它转化为UTF编码形式的char*再进行处理。
如:
jboolean isCopy = 0;
str = env->GetStringUTFChars(prompt, &isCopy);   //C 中是 (*env)->GetStringUTFChars(env,  str, &isCopy);  这里返回的char*有字符串结束符
 
如果想返回一个java的String类型的话,我们可以通过env->NewStringUTF命令用一个char*来创建一个jstring,然后让该jstring返回就可以。
如:jstring rtstr = env->NewStringUTF(tmpstr);
上面的GetStringUTFChars,ReleaseStringUTFChars,NewStringUTF都是JNI提供的处理String类型的函数,更多的JNI函数请查看jin.h。
 
注意在使用完你所转换之后的对象之后,需要显示调用 ReleaseStringUTFChars(JNIEnv*, jstring, const char*)方法,让JVM释放转换成UTF-8的string的对象的空间,如果不显示的调用的话,JVM中会一直保存 该对象,不会被垃圾回收器回收,因此就会导致内存溢出。
 
  下面是访问String的一些方法, C中:
  ◆const   char*GetStringUTFChars(JNIEnv*, jstring, jboolean*);  将jstring转换成为UTF-8格式的char*
  ◆const   jchar* GetStringChars(JNIEnv*, jstring, jboolean*);      将jstring转换成为Unicode格式的char*
  ◆ void    ReleaseStringUTFChars(JNIEnv*, jstring, const char*);  释放指向UTF-8格式的char*的指针
  ◆void     ReleaseStringChars(JNIEnv*, jstring, const jchar*);       释放指向Unicode格式的char*的指针
  ◆jstring  NewStringUTF)JNIEnv*, const char*);                          创建一个UTF-8格式的String对象
  ◆jstring  NewString(JNIEnv*, const jchar*, jsize);                      创建一个Unicode格式的String对象
  ◆jsize     GetStringUTFLength)(JNIEnv*, jstring);                       获取 UTF-8格式的char*的长度 
  ◆jsize     GetStringLength)(JNIEnv*, jstring);                            获取Unicode格式的char*的长 度
 
 
 
 
 
 
 
 
 
 
posted on 2012-11-01 11:14    阅读(903)  评论(0编辑  收藏  举报