这节我们讲解怎么将jni函数运用到我们的代码,这些都是我自己摸索了,肯定有更好的解决方法.但是,没那个多时间去研究了.
所以希望,有更好解决方法的大神,能指点指点.
<1. 将java当中参数传入的string转换成char*
JNIEXPORT jint JNICALL Java_com_viking_myapplication_JniMethod_NetFreeBuffer (JNIEnv *env, jobject jobj, jstring pBuffer){ char * pbuffer = (char *)env->GetStringUTFChars(pBuffer,0); //将java当中参数传入的string转换成char* jint result =Net_FreeBuffer(pbuffer); //Net_FreeBuffer() c代码的接口 env->ReleaseStringUTFChars(pBuffer,pbuffer); //释放内存 return result; }
<2. 通过java对象作为参数,传递数据.
JNIEXPORT jint JNICALL Java_com_viking_myapplication_JniMethod_NetImageSnap (JNIEnv *env, jobject jobj, jint tHandle,jobject ptImageSnap){ jclass jclazz = env->GetObjectClass(ptImageSnap); //通过对象获取jclass类 jfieldID uiImageIdID = env->GetFieldID(jclazz,"uiImageId","I"); //通过jclass,跟变量名,获取变量id jint a = env->GetIntField(ptImageSnap,uiImageIdID); //通过对象和变量id,获取Java对象中变量的值 jfieldID ucLightIndexID =env->GetFieldID(jclazz,"ucLightIndex","B"); jbyte b = (unsigned char)env->GetByteField(ptImageSnap,ucLightIndexID); jint result =Net_ImageSnap(a,b); return result; }
//创建java对象TImageUserInfo jclass jimageuserinfobean = env1->FindClass("com/viking/bean/TImageUserInfo"); //获取java对象的构造方法id jmethodID jimageuserinfobeanID = env1->GetMethodID(jimageuserinfobean,"<init>","()V"); //创建java对象 jobject jimageuserinfo = env1->NewObject(jimageuserinfobean,jimageuserinfobeanID);
<4. 在jni中,给创建出来的java对象中变量赋值
//通过java对象的jclass,跟类中变量名称,和变量的类型,获取变量的id
jfieldID ucVehicleColorID = env2->GetFieldID(jimageuserinfobean(Java对象的jclass),"ucVehicleColor"(变量的名称),"B"(变量类型));
//通过SetByteField,给变量赋值. env2->SetByteField(jimageuserinfo(java对象),ucVehicleColorID(java的变量的id),ptImageInfo->ucVehicleColor(值));
<5.jni中,怎么将对象中的值赋值给C结构体中
//javabean对象
public class TControlGate { public byte ucState; /*E_GateState*/ public byte[] ucReserved3; //这里我用的是byte[], 对应c中的char[]. 大家也可以用string,这样简单很多.
//我只所以用这个类型,是因为,后面讲解到面对无符号的参数我们该怎么转换. }
//c结构体
typedef struct
{ char ucState; /*E_GateState*/ char ucReserved[3]; }T_ControlGate;
//jni中的方法体
{
T_ControlGatet_controlGate; //初始化结构体
//通过ptControlGate Java对象,获取该对象的jclass.
// ptControlGate 是我在java中定义的bean类对象.里面的数据类型和c中结构体类型一致,或者可以相互转换. jclass jptcontrolgateclass = env->GetObjectClass(ptControlGate);
//通过jclass,获取里面的变量的id. jfieldID ucStateID = env->GetFieldID(jptcontrolgateclass,"ucState","B");
//通过对象和变量id,获取变量的值.且将值传入到结构体中. t_controlGate.ucState =(char)env->GetByteField(ptControlGate,ucStateID);
//这是一个byte数组
jfieldID ucReserved3ID = env->GetFieldID(jptcontrolgateclass,"ucReserved3","[B");
//通过GetObjectField(); 获取到jbytearray数组对象. jbyteArray ucreservedarr = (jbyteArray)env->GetObjectField(ptControlGate,ucReserved3ID);
//我这里将数组对象转换成char*. char* ucreser =(char*) env->GetByteArrayElements(ucreservedarr,0); jsize len = env->GetArrayLength(ucreservedarr);
//这里通过赋值,一个个赋值给结构体里面,也可以通过memcpy()等赋值. for(int x=0;x<len;x++){ t_controlGate.ucReserved[x] = ucreser[x]; }
int result = Net_GateSetup(tHandle,&t_controlGate);
}
<6. 返回值为自定义java对象.
JNIEXPORT jobject JNICALL Java_com_viking_myapplication_JniMethod_NetGetSdkVersion (JNIEnv *env, jobject jobj){
//这个是获取需要返回的java对象的jclass jclass sdkversioclass = env->FindClass("com/viking/bean/TGetSdkVersion");
//因为接口问题,所以我直接赋值一个char数组 char szversion[256]; int ptlen ; ptlen=(unsigned int)(256); jint result = Net_GetSdkVersion(szversion,&ptlen); //这是我们公司的接口,不想去改他的接口了,直接用,所以前面我只能这么定义了. jmethodID sdkverionid = env->GetMethodID(sdkversioclass,"<init>","()V"); //获取java的构造方法id jobject sdkversionobject = env->NewObject(sdkversioclass,sdkverionid); //创建java对象 jfieldID szversionid = env->GetFieldID(sdkversioclass,"szVersion","[B"); //获取对象的变量id jbyteArray szverionarr = env->NewByteArray((int)ptlen); //创建byte数组 jbyte * szv =(jbyte*)szversion; env->SetByteArrayRegion(szverionarr,0,(int)ptlen,szv); //将jbyte*类型的数据,赋值给jbyteArray中 env->SetObjectField(sdkversionobject,szversionid,szverionarr); //直接将jbyteArray变量,赋值给对象中. return sdkversionobject; //返回java对象. }
<7. 将jbyteArray 转换成Char*
char* ch = (char *)env->GetByteArrayElements(jbyteArray,0); //jbyteArray
<8.将char[] 转换成char*
char ch[] ="hhhh";
char * cha ;
memcpy(cha ,ch ,strlen(ch)); //
<9.将char[] 转换成jbyte*
char ch[] ="hhhh";
jbyte * jb ;
memcpy(jb, ch, strlen(ch));
<10.将jbyte* 数据赋值jbyteArray中
int n =6;
jbyte* jbb = (jbyte*)env->GetByteArrayElements(jbyteArray,0); //这个jbyteArray,可以是java传入的数据.
jbyteArray jba = env->NewByteArray(n); //创建一个jbyteArray 对象
env->SetByteArrayRegion(jbb,0,n,jba); //将jbyte* 中,从0到n的值,赋值给jbyteArray中.
<11
又下班了,今天就写着点了.
其他的就写下节了.(后面主要是讲,1.unsigned 类型数据,跟java中数据的转换.2.c中回调函数的解决 3.将这节没贴完的代码贴完)