无法从JNI设置Java int数组字段 我正在开发一个Android应用程序,我从C++中的一个LIB接收相机数据。我需要把这些数据从C++发送到java代码。为此,我正在使用JNI。我可以在java中从JNI和C++数据中设置不同的字段(比如相机的名称或类型),但是我不能设置ID字段,因为它是 uTn8*t < /Cord>数组。

无法从JNI设置Java int数组字段 我正在开发一个Android应用程序,我从C++中的一个LIB接收相机数据。我需要把这些数据从C++发送到java代码。为此,我正在使用JNI。我可以在java中从JNI和C++数据中设置不同的字段(比如相机的名称或类型),但是我不能设置ID字段,因为它是 uTn8*t < /Cord>数组。,java,c++,java-native-interface,Java,C++,Java Native Interface,我该怎么做 我已经尝试了几种方法来实现这一点,但每次我都遇到地址无效的SIGSEGV错误。对于我正在使用的其他字段 env->SetField(jobject,jfieldID,value) 方法,但是没有像intarray那样的方法,是吗? 因此,我试图通过调用类中的方法来设置此字段,并提供int数组作为参数,但此函数失败并返回SIGSEGV错误 然后,我在网上搜索,并试图通过设置字段 env->GetObjectField(jobject,jfieldID) 及 env->SetIntA

我该怎么做

我已经尝试了几种方法来实现这一点,但每次我都遇到地址无效的
SIGSEGV错误。对于我正在使用的其他字段

env->SetField(jobject,jfieldID,value)
方法,但是没有像
int
array那样的方法,是吗? 因此,我试图通过调用类中的方法来设置此字段,并提供
int
数组作为参数,但此函数失败并返回
SIGSEGV错误

然后,我在网上搜索,并试图通过设置字段

env->GetObjectField(jobject,jfieldID)

env->SetIntArrayRegion(金塔瑞,开始,结束,米塔瑞)
但是这里第一个方法总是返回null

JavaVM*mJVM//我的Java虚拟机
jobject mcameraoObject,mThreadObject//以前初始化以调用正确线程中的函数
void onReceiveCameraList(void*ptr,uint32\u t/*id*/,my::lib::Camera*arrayCamera,uint32\u t nbCameras){
JNIEnv*env;
mJVM->AttachCurrentThread(&env,nullptr);
如果(环境->例外检查())
返回;
//获取字段、方法ID、对象和类
jclass cameraClass=env->GetObjectClass(mCameraObject);
jfieldID camIDField=env->GetFieldID(cameraClass,“idCam”,“I”);
jfieldID camNameField=env->GetFieldID(cameraClass,“label”,“Ljava/lang/String;”);
jfieldID camConnectedField=env->GetFieldID(cameraClass,“connected”,“Z”);
jfieldID camTypeField=env->GetFieldID(cameraClass,“typeProduit”,“B”);
jmethodID CamReceptionId=env->GetMethodID(env->GetObjectClass(mThreadObject),“onCamerasReception”,“([Lcom/my/path/models/Camera;)V”);//Java函数
jobjectArray cameraArray=env->NewObjectArray(nbCameras、cameraClass、mCameraObject);//函数中的对象返回
//把摄像机放到向量机里
矢量摄像机;
如果(!vectorCameras.empty())
矢量摄影机。清除();
如果((arrayCamera!=nullptr)&&(nbCameras>0)){
对于(uint32_t i=0;iAllocObject(cameraClass);//要添加到cameraArray对象中的对象摄影机
//设置ID字段的我的数据///
金特·艾达瑞[16];
对于(int i=0;i<16;++i){
idArray[i]=cam.idCamera.data[i];//uint8\u t cam.idCamera.data[16]
}
/////////第一条路/////////
jmethodidsetidcammid=env->GetMethodID(env->GetObjectClass(camera),“setIDCam”,“([I)V”);
env->CallVoidMethod(摄像头、setIDCamMID、idArray);
/////////第二条路/////////
jintArray jintArray1=(jintArray)env->GetObjectField(摄像头,camIDField);
env->SetIntArrayRegion(金塔里1,0,16,爱达里);
//设定场:工作
env->SetObjectField(摄像头,camNameField,env->NewStringUTF((const char*)cam.labelCamera));
环境->设置工具字段(摄像头、摄像头连接字段、摄像头已连接);
jbyte型;
if(cam.typeCamera==my::lib::TYPE|1 | | cam.typeCamera==my::lib::TYPE|2 | | cam.typeCamera==my::lib::TYPE|3)//类型在JAVA中未知
类型=0;
其他的
类型=cam.type摄像机;
环境->设置字段(摄像机、摄像机类型字段、类型);
//将摄影机对象放入cameraArray对象中
Env- > StudioObjtARayRealEngor(CAMARAL数组,C++,相机);
}//为了
//使用cameraArray调用Java方法
env->CallVoidMethod(mThreadObject、CamReceptionId、dpCameraArray);
}//接受式摄像机
有人能告诉我我是否犯了错误或使用了错误的方式吗?

是否有其他方法来设置此数据?

对于第一种方法,您需要首先创建一个Java
int[]
,从
idArray
填充它,然后调用您的方法:

jintArray j_arr=env->NewIntArray(16);
env->SetIntArrayRegion(j_arr,0,16,Idaray);
环境->呼叫无效方法(摄像头、setIDCamMID、j_-arr);
第二种方法不起作用,因为您从未调用填充
idCam
字段的构造函数。 但是,您可以从JNI执行此操作:

env->SetObjectField(摄像头、摄像头、摄像头);

这产生了一个C++数组,其元素类型为“代码>金币< /代码>:

…不正确。
idArray
不是您尝试调用的Java方法的相应参数的正确类型(并且不会衰减为指向正确类型的指针)

另一方面,这

…可以,前提是该字段已包含对长度至少为16的
int[]
的引用。由于它不适用于您,我认为该字段的初始值不满足该标准

如果需要创建新的Java
int[]
,则

  • 使用JNI的
    NewIntArray()
    函数,该函数返回一个
    jintArray
    ,长度为指定的长度。然后
  • 使用适当的JNI方法设置元素(见下文),最后
  • 使用
    SetObjectField()
    将数组直接分配给目标对象的字段,或者使用对象的setter方法来分配数组,就像第一次尝试那样
  • 至于设置Java数组的元素,
    SetIntArrayRegion()
    可以很好地实现这一点(给定一个足够长的实际Java数组),但这确实需要您分配一个单独的原语本机数组(您的
    idArray
    ),从中复制val
        // MY DATA TO SET ID FIELD ///
        jint idArray[16];
            for (int i = 0; i < 16 ; ++i) {
                idArray[i] = cam.idCamera.data[i]; // uint8_t cam.idCamera.data[16]
            }
    
        ///////// FIRST WAY  /////////
        jmethodID setIDCamMID = env->GetMethodID(env->GetObjectClass(camera), "setIDCam", "([I)V");
        env->CallVoidMethod(camera, setIDCamMID, idArray);
    
        ///////// SECOND WAY /////////
            jintArray jintArray1 = (jintArray)env->GetObjectField(camera, camIDField);
            env->SetIntArrayRegion(jintArray1, 0, 16, idArray);
    
    // It is assumed here that the length of the array is sufficient, perhaps because
    // we just created this (Java) array.
    jint *idArray = (jint *) env->GetPrimitiveArrayCritical(jintArray1, NULL);
    
    for (uint32_t i = 0; i < nbCameras; ++i) {
        idArray[i] = cam.idCamera.data[i];
    }
    env->ReleasePrimitiveArrayCritical(jintArray1, idArray, 0);