NDK编程:JNI与Java,C++字符类型转换

来源:互联网 发布:java se 5.0下载 编辑:程序博客网 时间:2024/06/06 06:42

以前在做一个跨平台SDK项目中,需要用JNI对C++接口进行转换,供Android层进行调用,其类型转换问题,真是让人头痛不已,今日做以总结,希望帮助到有需要的朋友。


1.int类型参数传出到Java层

c++接口:

 int test( int  *out)   out参数作为传出的参数

Java接口:

int test( Integer out)   out参数作为传出的参数,注意:此处类型为Integer,调用时必须New一个Integer对象传入,后面不再赘述

JNI实现:

JNIEXPORT jint  JNICALL Java_com_XXX_test(JNIEnv *env, jobject obj, object out){    int num= 0;    //此处调用    int ret = test(&num);    jclass classInteger = (*env)->FindClass(env, "java/lang/Integer");    jfieldID fileIdIntegerValue = (*env)->GetFieldID( env, classInteger, "value", "I");             (*env)->SetIntField( env, out, fileIdIntegerValue, num);    return ret ;}

2.char* 转 String传出

C++:

int getName(char *name);  name为传出的参数

Java:

 int getNme(STRDATA  name) public class STRDATA {     public String str;}

JNI实现:

JNIEXPORT jint JNICALL Java_com_XXX_getName(JNIEnv *env, jobject obj, jobject name){    char dname[SIZE64] = {'\0'};    //此处调用    int ret = getName(dname);    if (ret == 0)    {        jclass objClass = (*env)->FindClass(env, "com/fos/sdk/STRDATA");        jfieldID fieldstr = (*env)->GetFieldID( env, objClass, "str", "Ljava/lang/String;" );        (*env)->SetObjectField( env, name, fieldstr, (*env)->NewStringUTF(env, dname) );    }    return ret;}

3.String 转 char* 传入

C++:

int setName(char* name)  name为传出的参数

Java:

 Int setNme(String  name)

JNI实现:

JNIEXPORT jint JNICALL Java_com_XXX_setName(JNIEnv *env, jobject obj, jstring name){    char nameTemp[SIZE64] = {'\0'};    const char *str = NULL;    str = (*env)->GetStringUTFChars(env, name, 0);    strcpy( nameTemp, str );    (*env)->ReleaseStringUTFChars(env, name, str);    //此处调用    int ret = setName(nameTemp);    return  ret;}

4.String 直接传出

C++实现:

 int getName(char* name)  name为传出的参数

Java:

 String getNme()

JNI:

JNIEXPORT jstring JNICALL Java_com_XXX_getName(JNIEnv *env, jobject obj){    char name[SIZE32] = {'\0'};    //此处调用    getName(name);    return (*env)->NewStringUTF(env , name);}

5.简单结构体传出

C++:

int getInfo( INFO  *info )Struct INFO{    int age;    Char *name;    Long high;}

Java:

int getInfo( INFO  info )Class INFO{    Public int age;    Public String name;    Public long high;}

JNI实现:

JNIEXPORT  jint JNICALL Java_com_XXX_getInfo(JNIEnv *env, jobject obj , jobject info ){    INFO  infotmp;    //此处调用    int ret = getInfo( &infotmp);    jclass objClass = (*env)->FindClass(env, "com/xxx/INFO ");    jfieldID fieldIDage = (*env)->GetFieldID( env, objClass, "age", "I" );    jfieldID fieldIDname = (*env)->GetFieldID( env, objClass, "name", "Ljava/lang/String;" );    jfieldID fieldIDhige = (*env)->GetFieldID( env, objClass, "high", "J" );    (*env)->SetIntField( env, info , fieldIDage , infotmp.age );    (*env)->SetObjectField( env, devstate,fieldIDname,(*env)->NewStringUTF(env, infotmp.name) );    (*env)->SetLongField( env, info , fieldIDhige , infotmp.high);     return ret;}

6.简单结构体传入

C++:

int SetInfo( INFO  *info )Struct INFO{    int age;    Char name[Size];    Long high;}

Java:

int SetInfo( INFO  info )Class INFO{    Public int age;    Public String name;    Public long high;}

JNI实现:

JNIEXPORT  jint JNICALL Java_com_XXX_SetInfo(JNIEnv *env, jobject obj , jobject info ){    INFO  infotmp;    jclass objClass = (*env)->FindClass(env, "com/xxx/INFO ");    jfieldID fieldIDage = (*env)->GetFieldID( env, objClass, "age", "I" );    jfieldID fieldIDname = (*env)->GetFieldID( env, objClass, "name", "Ljava/lang/String;" );    jfieldID fieldIDhige = (*env)->GetFieldID( env, objClass, "high", "J" );    jint  age = (*env)->GetIntField(env, info , fieldIDage );    infotmp.age = age ;    jstring name= (jstring) (*env)->GetObjectField(env, info , fieldIDname );    const char *dname= (name== 0) ? 0 : (*env)->GetStringUTFChars(env, name, 0);    strncpy( infotmp.name, dname, SIZE );  // size of name    (*env)->ReleaseStringUTFChars(env, name, dname);    jlong  high = (*env)->GetLongField(env, info , fieldIDhige );    infotmp.high = high ;    //此处调用    int ret = SetInfo(&infotmp);    return ret;}

7.带一维数组结构体传出

C++:

int GetInfo( INFO  *info )Struct INFO{    int  state[Size];    char name[Size][Size];}

Java:

int GetInfo( INFO  info )Class INFO{    Public int [ ]  state;    Public String[ ]  name;}

JNI实现:

JNIEXPORT  jint JNICALL Java_com_XXX_GetInfo(JNIEnv *env, jobject obj , jobject info ){    INFO  infotmp;    jclass objClass = (*env)->FindClass(env, "com/xxx/INFO ");    jfieldID fieldIDstate = (*env)->GetFieldID( env, objClass, "state", "[ I" );    jfieldID fieldIDname = (*env)->GetFieldID( env, objClass, "name", "[ Ljava/lang/String;" );     //此处调用    GetInfo( &infotmp);    jintArray intarry = (*env)->NewIntArray(env, SIZE);    (*env)->SetIntArrayRegion(env, intarry , 0, SIZE, infotmp.state);    (*env)->SetObjectField( env, info , fieldIDstate , intarry );    jclass strclass = (*env)->FindClass(env, "[Ljava/lang/String;");    jobjectArray objarry = (*env)->NewObjectArray(env, SIZE8, strclass, NULL);    for(int i = 0;i < SIZE; i++)    {        (*env)->SetObjectArrayElement(env, objarry, i, (*env)->NewStringUTF(env, infotmp.name[i]));    }    (*env)->SetObjectField( env, info , fieldIDname , objarry );    return 0;}

8.带一维数组结构体传入

C++:

int SetInfo( INFO  *info )Struct INFO{    int  state[Size];    char name[Size][Size];}

Java:

int  SetInfo( INFO  info )Class INFO{    Public int [ ]  state;    Public String[ ]  name;}

JNI实现:

JNIEXPORT jint JNICALL Java_com_XXX_SetInfo(JNIEnv *env, jobject obj, jobject info){    INFO  tempinfo ;    memset( &tempinfo , 0x00, sizeof(tempinfo ) );    jclass objClass = (*env)->FindClass(env, "com/xx/INFO ");    jfieldID fieldIDstate = (*env)->GetFieldID( env, objClass, "state", "[I" );    jfieldID fieldIDname = (*env)->GetFieldID( env, objClass, "name", "[ Ljava/lang/String;" );    jintArray jarry1 = (*env)->NewIntArray(env,SIZE);      jarry1 = (jintArray)(*env)->GetObjectField(env, info, fieldIDstate );    (*env)->GetIntArrayRegion(env,jarry1, 0, SIZE, tempinfo .state);    jclass strclass = (*env)->FindClass(env, "[Ljava/lang/String;");    jobjectArray objarry = (*env)->NewObjectArray(env, SIZE ,strclass, NULL);    objarry = (jobjectArray )(*env)->GetObjectField(env, info, fieldIDname );    for(int i = 0;i < SIZE; i++)    {    jstring  name = (*env)->GetObjectArrayElement(env, objarry , i);    const char *dname= (name== 0) ? 0 : (*env)->GetStringUTFChars(env, name, 0);    strncpy( infotmp.name[i], dname, SIZE );  // size of name    (*env)->ReleaseStringUTFChars(env, name, dname);    }    //此处调用    return SetInfo(&tempinfo );}

9.解决中文字符乱码问题

JNI实现:

memcpy(nodename, node[i].name, strlen(node[i].name)+1);jclass strClass = (*env)->FindClass(env, "java/lang/String");jmethodID ctorID =(*env)->GetMethodID(env,strClass, "<init>", "([BLjava/lang/String;)V");jbyteArray bytes = (*env)->NewByteArray(env,(jsize)strlen(nodename));(*env)->SetByteArrayRegion(env,bytes,0,(jsize)strlen(nodename),(jbyte*)(nodename));//转换字符编码jstring encoding = (*env)->NewStringUTF(env,"GB2312");jstring devname =  (jstring)(*env)->NewObject(env,strClass, ctorID, bytes, encoding);(*env)->SetObjectField( env, jobj, fieldIDname, devname);