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

这节我们讲解怎么将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.将这节没贴完的代码贴完)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值