JNI——Java与C++ API接口调用

1.类型转化

//jstr转char*
const char *chars = env->GetStringUTFChars(jstr, NULL);
//char*转jstring
jstring rtstr = env->NewStringUTF(chars);
//释放资源
env->ReleaseStringUTFChars(jstr, chars);
env->DeleteLocalRef(jstr);

//jobject转jclass
jclass clazz = (*env)->GetObjectClass(env, jobj);
jobject jobj = (*env)->AllocObject(env,jclass);

//获取String的jclass引用
jclass jstr = env->FindClass("Ljava/lang/String;");
//得到编码对象
jstring strencode = env->NewStringUTF("GB2312");
//数组长度
jsize alen = env->GetArrayLength(barr);
//对象元素
jobject obj = env->GetObjectArrayElement(bmps, i);

一维数组

//创建对象
jintArray aa = env-> NewIntArray(10);
int tmp[10];
for (int j = 0; j < 10; j++) {
    tmp[j] =j;
}
//添加元素
env->SetIntArrayRegion(aa, 0, 10, tmp);

二维数组

jobjectArray result;
//创建对象数组
result = env->NewObjectArray(10,clazz,NULL);
jclass clazz  = env->FindClass("[B");
jint tmp2[1024];//固定数组,注意别溢出
//jint *carr;
jintArray intArr;
for (int i = 0; i < 10; i++) {
    intArr = env->NewIntArray(10-i);
    //carr = env->GetIntArrayElements(intArr, NULL);
    for (int j = 0; j < 10; j++) {
        tmp2[j] = i + j;
        //carr[j] = i + j;
    }
    //一维数组赋值
    env->SetIntArrayRegion(intArr, 0, 10-i, tmp2);
    //设置对象元素,result为目标数组,i是位置索引,intArr是byte数组
    env->SetObjectArrayElement(result, i, intArr);
    env->DeleteLocalRef(intArr);
}

jni读取二位数组

//posxy是float[][]
int len = env->GetArrayLength(posxy);
    for (int i = 0; i < len; i++) {
        jobject farray = env->GetObjectArrayElement(posxy, i);
        int l = env->GetArrayLength((jfloatArray)farray);
        //flaot[]转float*
        jfloat *xy = env->GetFloatArrayElements((jfloatArray)farray, NULL);
        for (int j = 0; j < l; j++) {
            GLOGD("========>pfj: x|y=%.1f", xy[j]);
        }
    }

jni给java成员变量赋值

//class对象
jclass jclass_general = env->FindClass("com/pfj/demo/Response”);
//无参构造
jmethodID general_Constructor = env->GetMethodID(jclass_general, "<init>",()V”);
//得到实例对象
jobject jobject_general = env->NewObject(jclass_general, general_Constructor);
//成员变量 names,类型是float[]
jfieldID jfield = env->GetFieldID(jclass_general, “names”,[F”);
int size = 16; 
jfloatArray jfloatArray = env->NewFloatArray(size);
//flaot[]转float*
jfloat *arr_temp = env->GetFloatArrayElements(jfloatArray, NULL);
for (int j = 0; j < size; j++) {
    arr_temp[j] = j+100//赋值
}
//jfloatArray赋值
env->SetFloatArrayRegion(jfloatArray, 0, size, arr_temp);
//java成员变量赋值
env->SetObjectField(jobject_general, jfield, jfloatArray);
env->DeleteLocalRef(jfloatArray);   // free memory

2.关于FindClass

创建一个jclass的引用,创建int的class引用:jclass intClazz = env->FindClass(“com.xxx.xxx”);
其他类型:

Z boolean
B byte
C char
S short
I int
J long
F float
D double
[D double[]
Ljava/lang/String; String
[Ljava/lang/String; string[]

返回类实体数据:

public class Response {
    public float score;
    public int grade;
    public double number;
    public double[] corner;
    public String result;
    // public String result2[8];
}

jni返回Response[]对象数组:

static jobjectArray convert(JNIEnv *env, std::vector<Rersult> pv_responses) {
		// 对象class
        jclass jclass_general = env->FindClass("com/xxx/xxx/Response");
        if (jclass_general == NULL) {
            return NULL;
        }
        // 对象数组
        jobjectArray jresponses = env->NewObjectArray(pv_responses.size(), jclass_general, NULL);
        for (int i = 0; i < pv_responses.size(); ++i) {
        	// 构造方法ID
            jmethodID general_Constructor = env->GetMethodID(jclass_general, "<init>", "()V");
            if (general_Constructor == NULL) {
                return NULL;
            }
            // 构造对象
            jobject jobject_general = env->NewObject(jclass_general, general_Constructor);
            if (jobject_general == NULL) {
                return NULL;
            }
            // score
            jfieldID score = env->GetFieldID(jclass_general, "score", "F");
            if (score == NULL) {
                return NULL;
            }
            env->SetFloatField(jobject_general, score, pv_responses[i].score);
            
            // grade
            jfieldID grade = env->GetFieldID(jclass_general,"grade", "I");
            if (grade == NULL) {
                return NULL;
            }
            env->SetIntField(jobject_general, l_t, pv_responses[i].grade);// number
            jfieldID number = env->GetFieldID(jclass_general,"number", "D");
            if (number == NULL) {
                return NULL;
            }
            env->SetDoubleField(jobject_general, number, pv_responses[i].number);
            
            // corner
            jdoubleArray corner = env->NewDoubleArray(8); // 数组长度8
            env->SetDoubleArrayRegion(corner, 0, 8, pv_responses[i].corner);
            jfieldID cornerID = env->GetFieldID(jclass_general, "corner", "[D");
            env->SetObjectField(jobject_general, cornerID, corner);
            env->DeleteLocalRef(corner);
            
 			// result
            jstring jstring_result = env->NewStringUTF(pv_responses[i].result.c_str()); // string转jstring
            jfieldID jfield_result = env->GetFieldID(jclass_general, "result", "Ljava/lang/String;");
            env->SetObjectField(jobject_general, jfield_result, jstring_result);
            env->DeleteLocalRef(jstring_result);
            // String数组待补充...
            
            // 一个对象Response
            env->SetObjectArrayElement(jresponses, i, jobject_general);
        }
        env->DeleteLocalRef(jclass_general);

        return jresponses;
    }

3.log打印

#define GLOGD(format, ...) fprintf(stdout, "[%s %s] " format "\n", __FILE__, \
__FUNCTION__, ##__VA_ARGS__)
#define GLOGI(format, ...) fprintf(stdout, "[%s %s] " format "\n", __FILE__, \
__FUNCTION__, ##__VA_ARGS__)
#define GLOGW(format, ...) fprintf(stdout, "[%s %s] " format "\n", __FILE__, \
__FUNCTION__, ##__VA_ARGS__)
#define GLOGE(format, ...) fprintf(stderr, "[%s %s] " format "\n", __FILE__, \
__FUNCTION__, ##__VA_ARGS__)

4. 异常处理

如果在native方法中发生了异常,通过下面这段代码抛出一个Java可以接收的异常

jclass errCls;
env->ExceptionDescribe();
env->ExceptionClear();
errCls = env->FindClass(“java/lang/IOException”);
//抛出一个Java可以接收的异常
env->ThrowNew(errCls, "thrown from C++ code");

如果要抛出其他类型的异常,替换掉FindClass的参数即可。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值