您的位置:首页 > 移动开发 > Android开发

Android studio NDK开发 从入门到实践三

2017-12-05 16:48 369 查看
这节我们讲解怎么将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;
}
<3.  jni中创建java对象
//创建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.将这节没贴完的代码贴完)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息