Android C++ jni结构体数组传值Java

C++结构体定义,为Nanodet模型识别的结果,将其返回到Java层,其他的结构体定义可以参考依葫芦画瓢

typedef struct BoxInfoWithCenter {
    float x1;
    float y1;
    float x2;
    float y2;
    float cx;
    float cy;
    float score;
    int label;
} BoxInfoWithCenter;

typedef struct PlayPianoUnit{
    std::string pic_name;
    int PlayBarCount;
    int notehead_heigth_avg;
    int x;//当前小节左上角x
    int y;//当前小节左上角y
    int w;//当前小节左上角w
    int h;//当前小节左上角h
    std::vector<BoxInfoWithCenter> BoxesInCurrPlayBar;
    std::vector<int> BoxesOctave;
    std::vector<std::string> BoxesStep;
}PlayPianoUnit;

public static native PlayPianoUnit_Java[] detect(double threshold, double nms_threshold, String picFolderPath);

 Java层类定义

package com.journaldev.androidcameraxopencv;
public class Box
{
    public float x1,y1,x2,y2,cx,cy;
    private int label;
    private float score;

    public Box(float x1,float y1, float x2, float y2, float cx, float cy, int label, float score)
    {
        this.x1 = x1;
        this.y1 = y1;
        this.x2 = x2;
        this.y2 = y2;
        this.cx = cx;
        this.cy = cy;
        this.label = label;
        this.score = score;
    }
}
package com.journaldev.androidcameraxopencv;

public class PlayPianoUnit_Java
{
    public String pic_name;
    public int PlayBarCount;
    public int notehead_heigth_avg;
    public int x;//当前小节左上角x
    public int y;//当前小节左上角y
    public int w;//当前小节左上角w
    public int h;//当前小节左上角h
    public Box[] BoxesInCurrPlayBar=null;
    public Integer[] BoxesOctave=null;
    public String[] BoxesStep=null;


    public PlayPianoUnit_Java(String pic_name,int PlayBarCount, int notehead_heigth_avg, int x, int y, int w, int h, Box[] BoxesInCurrPlayBar, Integer[] BoxesOctave, String[] BoxesStep)
    {
        this.pic_name = pic_name;
        this.PlayBarCount = PlayBarCount;
        this.notehead_heigth_avg = notehead_heigth_avg;
        this.x = x;
        this.y = y;
        this.w = w;
        this.h = h;
        this.BoxesInCurrPlayBar = BoxesInCurrPlayBar;
        this.BoxesOctave = BoxesOctave;
        this.BoxesStep = BoxesStep;
    }
}
extern "C" JNIEXPORT jobjectArray JNICALL
Java_com_journaldev_androidcameraxopencv_NanoDet_detect(JNIEnv *env, jclass, jdouble threshold, jdouble nms_threshold, jstring picFolderPath)
{
    std::vector<PlayPianoUnit> result = get_play_piano_unit(env, threshold, nms_threshold, picFolderPath);
    //VINS_LOG("result size:%d", result.size());
    auto objectClass = env->FindClass("com/journaldev/androidcameraxopencv/PlayPianoUnit_Java");
    auto consID = (env)->GetMethodID(objectClass, "<init>",
                                     "(Ljava/lang/String;IIIIII[Lcom/journaldev/androidcameraxopencv/Box;[Ljava/lang/Integer;[Ljava/lang/String;)V");//Ljava/lang/String;
    jobjectArray ret = env->NewObjectArray(result.size(), objectClass, nullptr);
    //获取类中每一个变量的定义
    jfieldID pic_name = (env)->GetFieldID(objectClass, "pic_name", "Ljava/lang/String;");
    jfieldID PlayBarCount = (env)->GetFieldID(objectClass, "PlayBarCount", "I");
    jfieldID notehead_heigth_avg = (env)->GetFieldID(objectClass, "notehead_heigth_avg", "I");
    jfieldID x = (env)->GetFieldID(objectClass, "x", "I");
    jfieldID y = (env)->GetFieldID(objectClass, "y", "I");
    jfieldID w = (env)->GetFieldID(objectClass, "w", "I");
    jfieldID h = (env)->GetFieldID(objectClass, "h", "I");
    jfieldID BoxesInCurrPlayBar = (env)->GetFieldID(objectClass, "BoxesInCurrPlayBar","[Lcom/journaldev/androidcameraxopencv/Box;");
    jfieldID BoxesOctave = (env)->GetFieldID(objectClass, "BoxesOctave", "[Ljava/lang/Integer;");
    jfieldID BoxesStep = (env)->GetFieldID(objectClass, "BoxesStep", "[Ljava/lang/String;");

    for (jint i = 0; i < result.size(); i++)
    {
        auto arg1Class = env->FindClass("com/journaldev/androidcameraxopencv/Box");
        auto arg2Class = env->FindClass("java/lang/Integer");
        auto arg3Class = env->FindClass("java/lang/String");
        auto consID1 = (env)->GetMethodID(arg1Class, "<init>", "(FFFFFFIF)V");
        auto consID2 = (env)->GetMethodID(arg2Class, "<init>", "(I)V");
        auto consID3 = (env)->GetMethodID(arg3Class, "<init>", "(Ljava/lang/String;)V");
        jobjectArray ret1 = env->NewObjectArray(result[i].BoxesInCurrPlayBar.size(), arg1Class, nullptr);
        jobjectArray ret2 = env->NewObjectArray(result[i].BoxesOctave.size(), arg2Class, nullptr);
        jobjectArray ret3 = env->NewObjectArray(result[i].BoxesStep.size(), arg3Class, nullptr);

        jfieldID x1 = (env)->GetFieldID(arg1Class, "x1", "F");
        jfieldID y1 = (env)->GetFieldID(arg1Class, "y1", "F");
        jfieldID x2 = (env)->GetFieldID(arg1Class, "x2", "F");
        jfieldID y2 = (env)->GetFieldID(arg1Class, "y2", "F");
        jfieldID cx = (env)->GetFieldID(arg1Class, "cx", "F");
        jfieldID cy = (env)->GetFieldID(arg1Class, "cy", "F");
        jfieldID label = (env)->GetFieldID(arg1Class, "label", "I");
        jfieldID score = (env)->GetFieldID(arg1Class, "score", "F");

        for(jint a=0;a<result[i].BoxesInCurrPlayBar.size();a++)
        {
            jobject obj1 = env->NewObject(arg1Class, consID1, result[i].BoxesInCurrPlayBar[a].x1,
                                                              result[i].BoxesInCurrPlayBar[a].y1,
                                                              result[i].BoxesInCurrPlayBar[a].x2,
                                                              result[i].BoxesInCurrPlayBar[a].y2,
                                                              result[i].BoxesInCurrPlayBar[a].cx,
                                                              result[i].BoxesInCurrPlayBar[a].cy,
                                                              result[i].BoxesInCurrPlayBar[a].label,
                                                              result[i].BoxesInCurrPlayBar[a].score);//
            env->SetFloatField(obj1, x1, (jfloat) result[i].BoxesInCurrPlayBar[a].x1);
            env->SetFloatField(obj1, y1, (jfloat) result[i].BoxesInCurrPlayBar[a].y1);
            env->SetFloatField(obj1, x2, (jfloat) result[i].BoxesInCurrPlayBar[a].x2);
            env->SetFloatField(obj1, y2, (jfloat) result[i].BoxesInCurrPlayBar[a].y2);
            env->SetFloatField(obj1, cx, (jfloat) result[i].BoxesInCurrPlayBar[a].cx);
            env->SetFloatField(obj1, cy, (jfloat) result[i].BoxesInCurrPlayBar[a].cy);
            env->SetIntField(obj1, label, (jint) result[i].BoxesInCurrPlayBar[a].label);
            env->SetFloatField(obj1, score, (jfloat) result[i].BoxesInCurrPlayBar[a].score);
            //obj1 = env->PopLocalFrame(obj1);
            env->SetObjectArrayElement(ret1, a, obj1);
            env->DeleteLocalRef(obj1);
        }

        for(jint b=0;b<result[i].BoxesOctave.size();b++)
        {
            jint octave_int = result[i].BoxesOctave[b];
            jobject obj2 = env->NewObject(arg2Class, consID2, octave_int);//
            //obj2 = env->PopLocalFrame(obj2);
            env->SetObjectArrayElement(ret2, b, obj2);
            env->DeleteLocalRef(obj2);
        }

        for(jint c=0;c<result[i].BoxesStep.size();c++)
        {
            jstring step_str = env->NewStringUTF(result[i].BoxesStep[c].c_str());
            jobject obj3 = env->NewObject(arg3Class, consID3, step_str);//
            //obj3 = env->PopLocalFrame(obj3);
            env->SetObjectArrayElement(ret3, c, obj3);
            env->DeleteLocalRef(obj3);
        }

        jstring arg = env->NewStringUTF(result[i].pic_name.c_str());
        jobject obj = env->NewObject(objectClass, consID, arg,result[i].PlayBarCount, result[i].notehead_heigth_avg, result[i].x, result[i].y, result[i].w, result[i].h, ret1, ret2, ret3);//
        env->SetObjectField(obj, pic_name, arg);
        env->SetIntField(obj, PlayBarCount, (jint) result[i].PlayBarCount);
        env->SetIntField(obj, notehead_heigth_avg, (jint) result[i].notehead_heigth_avg);
        env->SetIntField(obj, x, (jint) result[i].x);
        env->SetIntField(obj, y, (jint) result[i].y);
        env->SetIntField(obj, w, (jint) result[i].w);
        env->SetIntField(obj, h, (jint) result[i].h);
        env->SetObjectField(obj, BoxesInCurrPlayBar, ret1);
        env->SetObjectField(obj, BoxesOctave, ret2);
        env->SetObjectField(obj, BoxesStep, ret3);
        env->SetObjectArrayElement(ret, i, obj);
        env->DeleteLocalRef(obj);
    }
    return ret;
}
public PlayPianoUnit_Java[] play_info = com.journaldev.androidcameraxopencv.NanoDet.detect(threshold, nms_threshold, picFolderPath);

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要将JNI中的char*类型转换为Java中的byte数组,可以按照以下步骤进行操作: 1. 获取char*类型字符串的长度,使用strlen()函数可以获取。 2. 创建一个jbyteArray类型的Java数组,长度为字符串长度,使用NewByteArray()函数可以创建。 3. 将char*类型字符串转换为jbyte类型数组,使用jbyte*类型的指针指向char*类型字符串,然后使用SetByteArrayRegion()函数将每个char类型元素转换为jbyte类型并设置到Java数组中。 4. 释放char*类型字符串的内存空间,使用free()函数释放。 下面是一个示例代码: ```c++ JNIEXPORT jbyteArray JNICALL Java_com_example_MyClass_charToByteArray(JNIEnv *env, jobject obj, jcharArray charArray) { // 将jcharArray类型转换为jchar类型指针 jchar *chars = env->GetCharArrayElements(charArray, NULL); // 获取字符串长度 int len = strlen(chars); // 创建jbyteArray类型的Java数组 jbyteArray byteArray = env->NewByteArray(len); // 将char*类型字符串转换为jbyte类型的数组 jbyte *bytes = (jbyte*)chars; env->SetByteArrayRegion(byteArray, 0, len, bytes); // 释放char*类型字符串的内存空间 free(chars); // 返回jbyteArray类型的Java数组 return byteArray; } ``` 在上面的示例代码中,我们首先将输入的jcharArray类型转换为jchar类型指针,然后获取字符串长度。接着,我们使用NewByteArray()函数创建一个长度为字符串长度的jbyteArray类型的Java数组。然后,我们将jchar类型指针转换为jbyte类型指针,并使用SetByteArrayRegion()函数将每个char类型元素转换为jbyte类型并设置到Java数组中。最后,我们使用free()函数释放char*类型字符串的内存空间,并返回jbyteArray类型的Java数组。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值