在JNI操作中最多见的即为从c/c++中获取结构体和设置java信息到结构体中功能,具体实现例子如下。
C 结构体如下
typedef struct _NPC_S_PVM_IMD_CFG_DEV_RECORD_PLAN
{
NPC_INT iChNo;
NPC_INT iRecState;
NPC_INT iPacketLength;
NPC_INT iPreRecord;
NPC_BOOL bOpenAudio;
NPC_INT iRecStream;
NPC_BOOL bOpenGeneral;
NPC_BOOL bOpenCheckAlarm;
NPC_BOOL bOpenInputAlarm;
struct _WeekSect{
struct _TimeSect{
NPC_BOOL bOpenGeneral;
NPC_BOOL bOpenCheckAlarm;
NPC_BOOL bOpenInputAlarm;
NPC_S_TD_TIME tBeginTime;
NPC_S_TD_TIME tEndTime;
} tTimeSect[NPC_D_PVM_CFG_REC_PLAN_TIME_SECT_NUM];
} tWeekSect[7];
NPC_CHAR sRecordMode[32];
NPC_BOOL bRedundancy;
} NPC_S_PVM_IMD_CFG_DEV_RECORD_PLAN, *PNPC_S_PVM_IMD_CFG_DEV_RECORD_PLAN;
JAVA类对应如下 位于 com/player/source/下
public class TDevRecordPlanEx {
public int iChNo;
public int iRecState;
public int iPacketLength;
public int iPreRecord;
public int iRecStream;
public int bOpenAudio;
public boolean bOpenGeneral;
public boolean bOpenCheckAlarm;
public boolean bOpenInputAlarm;
public String sRecordMode;
public boolean bRedundancy;
public TDevRecordPlanExWeekSect [] tDevRecordPlanExWeekSects = new TDevRecordPlanExWeekSect[7];
}
/*子类,数组*/
public class TDevRecordPlanExWeekSect {
public TDevRecordPlanExTimeSect[] tTimeSect = new TDevRecordPlanExTimeSect[6];
}
/*子类*/
public class TDevRecordPlanExTimeSect {
public boolean bOpenGeneral;
public boolean bOpenCheckAlarm;
public boolean bOpenInputAlarm;
public TDateTime tBeginTime;
public TDateTime tEndTime;
}
/*时间类*/
public final class TDateTime implements Serializable {
private static final long serialVersionUID = -5238783596803259572L;
public int iYear; // 年
public int iMonth; // 月
public int iDay; // 日
public int iHour; // 时
public int iMinute; // 分
public int iSecond; // 秒
public int iMinsecond; // 毫秒
public int iweek;// 周 1-7 week=1为星期日,week=7为星期六
@Override
public String toString() {
return "TDateTime [iYear=" + iYear + ", iMonth=" + iMonth + ", iDay="
+ iDay + ", iHour=" + iHour + ", iMinute=" + iMinute
+ ", iSecond=" + iSecond + ", iMinsecond=" + iMinsecond
+ ", iweek=" + iweek + "]";
JNI获取设置如下(c结构体至JAVA)
JNIEXPORT jint JNICALL Java_com_stream_NewAllStreamParser_CameraGetDevRecordPlan(
JNIEnv* env, jclass clazz, jint pMONCamera, jint in_jiChNo, jobject out_joCfgObjDevRecordPlan)
{
NPC_I_MPI_MON_Camera* pCamera;
PNPC_S_PVM_IMD_CFG_DEV_RECORD_PLAN pCfgBody = NULL;
NPC_INT iCfgBodyLen = 0;
NPC_S_PVM_IMD_CFG_DEV_RECORD_PLAN tCfgBody = {0};
pCamera = (NPC_I_MPI_MON_Camera*)((jint*)pMONCamera);
if ( pCamera == NULL )
return 99;
tCfgBody.iChNo = in_jiChNo;
//---------------------------------------------------------------------------
//获取配置,返回0:表示成功,其它表示失败
if ( pCamera->NPC_F_MPI_MON_Camera_GetConfig(
NPC_D_PVM_CFG_FUNCID_DEV_RECORD_PLAN,
(PNPC_BYTE)&tCfgBody,
sizeof(tCfgBody),
(PNPC_BYTE*)&pCfgBody,
&iCfgBodyLen
) != 0 )
{
return 2;
}
if ( pCfgBody == NULL )
{
return 3;
}
if ( iCfgBodyLen != (NPC_INT)sizeof(NPC_S_PVM_IMD_CFG_DEV_RECORD_PLAN) )
{
//释放数据缓冲区,由底层分配的缓冲区
pCamera->NPC_F_MPI_MON_Camera_ReleaseBuf(
(PNPC_BYTE)pCfgBody//[IN]缓冲区,由底层分配的缓冲区
);
pCfgBody = NULL;
return 4;
}
//---------------------------------------------------------------------------
BS_SetObjectFieldValue_Int(env, out_joCfgObjDevRecordPlan, "iChNo", pCfgBody->iChNo);
BS_SetObjectFieldValue_Int(env, out_joCfgObjDevRecordPlan, "iRecState", pCfgBody->iRecState);
BS_SetObjectFieldValue_Int(env, out_joCfgObjDevRecordPlan, "iPacketLength", pCfgBody->iPacketLength);
BS_SetObjectFieldValue_Int(env, out_joCfgObjDevRecordPlan, "iPreRecord", pCfgBody->iPreRecord);
BS_SetObjectFieldValue_Int(env, out_joCfgObjDevRecordPlan, "bOpenAudio", pCfgBody->bOpenAudio);
BS_SetObjectFieldValue_Int(env, out_joCfgObjDevRecordPlan, "iRecStream", pCfgBody->iRecStream);
BS_SetObjectFieldValue_Boolean(env, out_joCfgObjDevRecordPlan, "bOpenGeneral", pCfgBody->bOpenGeneral);
BS_SetObjectFieldValue_Boolean(env, out_joCfgObjDevRecordPlan, "bOpenCheckAlarm", pCfgBody->bOpenCheckAlarm);
BS_SetObjectFieldValue_Boolean(env, out_joCfgObjDevRecordPlan, "bOpenInputAlarm", pCfgBody->bOpenInputAlarm);
BS_SetObjectFieldValue_String(env, out_joCfgObjDevRecordPlan, "sRecordMode", pCfgBody->sRecordMode);
BS_SetObjectFieldValue_Boolean(env, out_joCfgObjDevRecordPlan, "bRedundancy", pCfgBody->bRedundancy);
/*循环读取,赋值*/
jclass objectClass = (env)->GetObjectClass(out_joCfgObjDevRecordPlan);//TDevRecordPlanExWeekSect类
jfieldID arrayfieldIdWeek= (env)->GetFieldID(objectClass,"tDevRecordPlanExWeekSects","[Lcom/Player/Source/TDevRecordPlanExWeekSect;"); //TDevRecordPlanExWeekSect 里面tDevRecordPlanExWeekSects数组变量ID
jclass jcWeekSect = (env)->FindClass("com/Player/Source/TDevRecordPlanExWeekSect");//tDevRecordPlanExWeekSects类
jobjectArray obj_arrayWeekSect = (env)->NewObjectArray(6, jcWeekSect, NULL);
jclass jcTimeSect = (env)->FindClass("com/Player/Source/TDevRecordPlanExTimeSect");//获取tTimeSect对象
jfieldID arrayfieldTime= (env)->GetFieldID(jcWeekSect,"tTimeSect","[Lcom/Player/Source/TDevRecordPlanExTimeSect;"); //TDevRecordPlanExTimeSect 里面tTimeSect数组变量ID
jclass jcDateTime = (env)->FindClass("com/Player/Source/TDateTime");//获取tDateTime对象
jfieldID fieldBeginTime = (env)->GetFieldID(jcTimeSect,"tBeginTime","Lcom/Player/Source/TDateTime;"); //TDevRecordPlanExTimeSect 里面beginTime
jfieldID fieldEndTime = (env)->GetFieldID(jcTimeSect,"tEndTime","Lcom/Player/Source/TDateTime;"); //TDevRecordPlanExTimeSect 里面beginTime
if((pCfgBody->tWeekSect) != NULL){
for(int i = 0 ; i < 6 ;i++){
if((pCfgBody->tWeekSect[i].tTimeSect) != NULL){
jobject obj_weekSect = (env)->AllocObject(jcWeekSect);//实例化类对象
jobjectArray obj_arrayTimeSect = (env)->NewObjectArray(7, jcTimeSect, NULL);
for(int j = 0;j < 7 ; j++){
jobject obj_TimeSect = (env)->AllocObject(jcTimeSect);
/*布放设置*/
BS_SetObjectFieldValue_Boolean(env,obj_TimeSect,"bOpenGeneral",pCfgBody->tWeekSect[i].tTimeSect[j].bOpenGeneral);
BS_SetObjectFieldValue_Boolean(env,obj_TimeSect,"bOpenCheckAlarm",pCfgBody->tWeekSect[i].tTimeSect[j].bOpenCheckAlarm);
BS_SetObjectFieldValue_Boolean(env,obj_TimeSect,"bOpenInputAlarm",pCfgBody->tWeekSect[i].tTimeSect[j].bOpenInputAlarm);
/*时间设置*/
jobject beginTime = (env)->AllocObject(jcDateTime);
jobject endTime = (env)->AllocObject(jcDateTime);
BS_SetObjectFieldValue_Int(env, beginTime, "iHour", pCfgBody->tWeekSect[i].tTimeSect[j].tBeginTime.ucHour);
BS_SetObjectFieldValue_Int(env, beginTime, "iMinute", pCfgBody->tWeekSect[i].tTimeSect[j].tBeginTime.ucMin);
BS_SetObjectFieldValue_Int(env, beginTime, "iSecond", pCfgBody->tWeekSect[i].tTimeSect[j].tBeginTime.ucSec);
BS_SetObjectFieldValue_Int(env, endTime, "iHour", pCfgBody->tWeekSect[i].tTimeSect[j].tEndTime.ucHour);
BS_SetObjectFieldValue_Int(env, endTime, "iMinute", pCfgBody->tWeekSect[i].tTimeSect[j].tEndTime.ucMin);
BS_SetObjectFieldValue_Int(env, endTime, "iSecond", pCfgBody->tWeekSect[i].tTimeSect[j].tEndTime.ucSec);
env->SetObjectField(obj_TimeSect,fieldBeginTime,beginTime);//对obj_TimeSect中begin time属性进行赋值
env->SetObjectField(obj_TimeSect,fieldEndTime,endTime);//对obj_TimeSect中begin time属性进行赋值
/*设置数组值*/
env->SetObjectArrayElement(obj_arrayTimeSect,j,obj_TimeSect);//给timeSect中某个元素赋值
}
env->SetObjectField(obj_weekSect,arrayfieldTime,obj_arrayTimeSect);//对obj_weekSect中tTimeSect属性进行赋值
(env)->SetObjectArrayElement(obj_arrayWeekSect, i, obj_weekSect);//给weekSect某个元素进行赋值
}
}
}
(env)->SetObjectField(out_joCfgObjDevRecordPlan,arrayfieldIdWeek,obj_arrayWeekSect);//设置objectClass中tWeekSect赋值
env->DeleteLocalRef(objectClass);//释放jclass
env->DeleteLocalRef(jcWeekSect);//释放jclass
env->DeleteLocalRef(jcTimeSect);//释放jclass
env->DeleteLocalRef(jcDateTime);//释放jclass
//释放数据缓冲区,由底层分配的缓冲区
pCamera->NPC_F_MPI_MON_Camera_ReleaseBuf(
(PNPC_BYTE)pCfgBody//[IN]缓冲区,由底层分配的缓冲区
);
pCfgBody = NULL;
return 0;
}设置如下(java类至c结构体)*/
JNIEXPORT jint JNICALL Java_com_stream_NewAllStreamParser_CameraSetDevRecordPlan(
JNIEnv* env, jclass clazz, jint pMONCamera, jobject in_joCfgObjDevRecordPlan)
{
NPC_I_MPI_MON_Camera* pCamera;
NPC_S_PVM_IMD_CFG_DEV_RECORD_PLAN tCfgBody = {0};
pCamera = (NPC_I_MPI_MON_Camera*)((jint*)pMONCamera);
if ( pCamera == NULL){
return 99;
}
if( in_joCfgObjDevRecordPlan == NULL){
return 98;
}
tCfgBody.iChNo = BS_GetObjectFieldValue_Int(env, in_joCfgObjDevRecordPlan, "iChNo");
tCfgBody.iRecState = BS_GetObjectFieldValue_Int(env, in_joCfgObjDevRecordPlan, "iRecState");
tCfgBody.iPacketLength = BS_GetObjectFieldValue_Int(env, in_joCfgObjDevRecordPlan, "iPacketLength");
tCfgBody.iPreRecord = BS_GetObjectFieldValue_Int(env, in_joCfgObjDevRecordPlan, "iPreRecord");
tCfgBody.bOpenAudio = BS_GetObjectFieldValue_Int(env, in_joCfgObjDevRecordPlan, "bOpenAudio");
tCfgBody.iRecStream = BS_GetObjectFieldValue_Int(env, in_joCfgObjDevRecordPlan, "iRecStream");
tCfgBody.bOpenGeneral = BS_GetObjectFieldValue_Boolean(env, in_joCfgObjDevRecordPlan, "bOpenGeneral");
tCfgBody.bOpenCheckAlarm = BS_GetObjectFieldValue_Boolean(env, in_joCfgObjDevRecordPlan, "bOpenCheckAlarm");
tCfgBody.bOpenInputAlarm = BS_GetObjectFieldValue_Boolean(env, in_joCfgObjDevRecordPlan, "bOpenInputAlarm");
/*雄迈属性*/
BS_GetObjectFieldValue_String(env, in_joCfgObjDevRecordPlan, "sRecordMode", tCfgBody.sRecordMode, sizeof(tCfgBody.sRecordMode));
tCfgBody.bRedundancy = BS_GetObjectFieldValue_Boolean(env,in_joCfgObjDevRecordPlan,"bRedundancy");
jclass objectClass = (env)->GetObjectClass(in_joCfgObjDevRecordPlan);//TDevRecordPlanExWeekSect类,通过object 获取class
jfieldID arrayfieldIdWeek= (env)->GetFieldID(objectClass,"tDevRecordPlanExWeekSects","[Lcom/Player/Source/TDevRecordPlanExWeekSect;"); //TDevRecordPlanExWeekSect 里面tDevRecordPlanExWeekSects数组变量ID
jclass jcWeekSect = (env)->FindClass("com/Player/Source/TDevRecordPlanExWeekSect");//tDevRecordPlanExWeekSects类
jobjectArray obj_arrayWeekSect = (jobjectArray)(env->GetObjectField(in_joCfgObjDevRecordPlan,arrayfieldIdWeek)); ;
jclass jcTimeSect = (env)->FindClass("com/Player/Source/TDevRecordPlanExTimeSect");//获取tTimeSect对象
jfieldID arrayfieldTime= (env)->GetFieldID(jcWeekSect,"tTimeSect","[Lcom/Player/Source/TDevRecordPlanExTimeSect;"); //TDevRecordPlanExTimeSect 里面tTimeSect数组变量ID
jclass jcDateTime = (env)->FindClass("com/Player/Source/TDateTime");//获取tDateTime对象
jfieldID fieldBeginTime = (env)->GetFieldID(jcTimeSect,"tBeginTime","Lcom/Player/Source/TDateTime;"); //TDevRecordPlanExTimeSect 里面beginTime
jfieldID fieldEndTime = (env)->GetFieldID(jcTimeSect,"tEndTime","Lcom/Player/Source/TDateTime;"); //TDevRecordPlanExTimeSect 里面beginTime
if(obj_arrayWeekSect != NULL){
for(int i = 0 ; i < 6; i++){
jobject joWeekSect = env->GetObjectArrayElement(obj_arrayWeekSect,i);
jobjectArray joArrayTimeSect =(jobjectArray)(env->GetObjectField(joWeekSect,arrayfieldTime));
if(joArrayTimeSect != NULL){
for(int j = 0;j < 7; j++){
jobject joTimeSeck = env->GetObjectArrayElement(joArrayTimeSect,j);
tCfgBody.tWeekSect[i].tTimeSect[j].bOpenGeneral = (NPC_BOOL)BS_GetObjectFieldValue_Boolean(env,joTimeSeck,"bOpenGeneral");
tCfgBody.tWeekSect[i].tTimeSect[j].bOpenCheckAlarm = (NPC_BOOL)BS_GetObjectFieldValue_Boolean(env,joTimeSeck,"bOpenCheckAlarm");
tCfgBody.tWeekSect[i].tTimeSect[j].bOpenInputAlarm = (NPC_BOOL)BS_GetObjectFieldValue_Boolean(env,joTimeSeck,"bOpenInputAlarm");
/*时间赋值*/
jobject beginTime = env->GetObjectField(joTimeSeck,fieldBeginTime);
jobject endTime = env->GetObjectField(joTimeSeck,fieldEndTime);
tCfgBody.tWeekSect[i].tTimeSect[j].tBeginTime.ucHour = BS_GetObjectFieldValue_Int(env,beginTime,"iHour");
tCfgBody.tWeekSect[i].tTimeSect[j].tBeginTime.ucMin = BS_GetObjectFieldValue_Int(env,beginTime,"iMinute");
tCfgBody.tWeekSect[i].tTimeSect[j].tBeginTime.ucSec = BS_GetObjectFieldValue_Int(env,beginTime,"iSecond");
tCfgBody.tWeekSect[i].tTimeSect[j].tEndTime.ucHour = BS_GetObjectFieldValue_Int(env,endTime,"iHour");
tCfgBody.tWeekSect[i].tTimeSect[j].tEndTime.ucMin = BS_GetObjectFieldValue_Int(env,endTime,"iMinute");
tCfgBody.tWeekSect[i].tTimeSect[j].tEndTime.ucSec = BS_GetObjectFieldValue_Int(env,endTime,"iSecond");
}
}
}
}
env->DeleteLocalRef(objectClass);//释放jclass
env->DeleteLocalRef(jcWeekSect);//释放jclass
env->DeleteLocalRef(jcTimeSect);//释放jclass
env->DeleteLocalRef(jcDateTime);//释放jclass
return pCamera->NPC_F_MPI_MON_Camera_SetConfig(
NPC_D_PVM_CFG_FUNCID_DEV_RECORD_PLAN,//[IN]配置功能ID,参见NPC_D_PVM_CFG_FUNCID_*定义
(PNPC_BYTE)&tCfgBody,//[IN]配置数据缓冲区,配置数据结构参见NPC_PVM_OrderCfgDef.h文件中的定义
sizeof(tCfgBody)//[IN]配置数据长度
);
}