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

这节我们开始讲,c/c++中 unsigned 类型数据,跟java中数据类型的转换.和c/c++中回调函数的解决


1.unsigned 类型数据,跟java中数据的转换.

这里首先说下java和c基本数据类型所占空间大小.

java        jni             c/c++  空间

boolean    jboolean   bool  8

byte       jbyte      char  unsigned char  8

char       jchar      short unsigned short 16

short      jshort     shortunsigned short16

int        jint       int   unsigned int 32

long       jlong      32

float      jfloat     32

double     jdouble    64


上图可以看出,在c中的char只有一个字节,而java中的char有两个字节.那么出现几个问题.

   <1.我怎么讲c中的char转换成java中的char?

(1.这个当然可以这个当然是可以直接复制. 从一个字节转换成两个字节,不会出现什么丢失的. 

jchar ch = (jchar)c; //大概意思就这样.

(2.为什么要转换成java的char类型呢?为什么不直接转换成byte类型呢?它们都是一个字节的.

jbyte bt  =(jbyte)c;

   <2.如果是unsigned char呢? 

(1.无符号的char也是一个字节,你可以转换成byte字节. 

   <3.char数组和unsigned char数组呢?

(1. char*可以通过env提供的方法,直接转换成string

char * ch;

jstring str = env->NewStringUTF(ch); 

(2. unsigned char*转换成String可能会出现乱码的情况,那么我们可以转换成byte数组啊. 

unsigned char* ch;

jbyte* bt = (jbyte*)ch; //转成byte数组

jbyteArray arr = env->NewByteArray(strlen(ch));

env->SetByteArrayRegion(arr,0,strlen(ch),bt); //将bt赋值给jbytearray了.

这下都给你bytearray 的java数组对象了,还不是为所欲为?

(3.jbyteArray转换成unsiged char*?

jbyteArray arr;

unsigned char* ch = (unsigned char*)env->GetByteArrayElements(arr,0); //就是这么简单

<4. char[] 和 char* 转换

2.c中回调函数的解决

   <1.先给个c接口

//回调接口

   typedef void (_stdcall *NET_FIND_DEVICE_CALLBACK)(T_RcvMsg *ptFindDevice, void *pUserData);

//回调函数
NET_API E_ReturnCode _stdcall Net_FindDevice(NET_FIND_DEVICE_CALLBACK func, void *pUserData);

<2.怎么解决这回调函数呢?我是这么解决的.

(1.先写netfindDevice的本地方法

	JNIEXPORT jint JNICALL Java_com_viking_myapplication_JniMethod_NetFindDevice
        	(JNIEnv *env, jobject jobj, jstring pUserData){
		LOGE("Java_com_viking_myapplication_JniMethod_NetFindDevice");
		jfindclass = env->GetObjectClass(jobj);
		jfindobject = jobj;
		char* puserdata = (char*)env->GetStringUTFChars(pUserData,0);
		jint result = Net_FindDevice(NET_FIND_DEVICE_CALLBACK1,(void*)puserdata);
		return result;
	}
	
	(2.实现回调方法
	void NET_FIND_DEVICE_CALLBACK1(T_RcvMsg *ptFindDevice, void *pUserData){
		//java回调方法
   		jmethodID jmethodid = env1->GetMethodID(jfindclass,"NetFindDeviceCallBack","(Lcom/viking/bean/TRcvMsg;Ljava/lang/String;)V");
    		  jclass jtrcvmsgclass = env1->FindClass("com/viking/bean/TRcvMsg");
    		jmethodID jtrcvmsgid= env1->GetMethodID(jtrcvmsgclass,"<init>","()V");
		//创建回调方法的参数的java对象
    		jobject jtrcvmsgobj = env1->NewObject(jtrcvmsgclass,jtrcvmsgid);
    		jclass jtnetsetupclass = env1->FindClass("com/viking/bean/TNetSetup");
    		jclass jtmacsetupclass = env1->FindClass("com/viking/bean/TMACSetup");
    		jmethodID  jtnetsetupid = env1->GetMethodID(jtnetsetupclass,"<init>","()V");
    		jmethodID  jtmacsetupid = env1->GetMethodID(jtmacsetupclass,"<init>","()V");
    		jobject jtnetsetupobj =env1 ->NewObject(jtnetsetupclass,jtnetsetupid); //对象一
    		  jobject jtmacsetupobj =env1 ->NewObject(jtmacsetupclass,jtmacsetupid); //对象二
		
			*******************给回调方法的参数赋值*************************
    		
		jstring puserdata = env1->NewStringUTF((char*)pUserData);
		//调用java中回调方法,参数(jtrcvmsgobj,puserdata);
    		env1->CallVoidMethod(jfindobject,jmethodid,jtrcvmsgobj,puserdata);
	}
(3.java中被调用的回调方法
	/**
 	* @param tRcvMsg
 	* @param pUserData
	 * 查找设备
 	*/
	public void NetFindDeviceCallBack(TRcvMsg tRcvMsg,String pUserData){
    		Log.e("TAG","NetFindDeviceCallBack");
    		if (mFindDeviceCallBack!=null){
        		mFindDeviceCallBack.CallBack(tRcvMsg,pUserData);
    		}
	}



好像没什么好讲的.下节就讲讲jni开发中遇到哦bug吧.






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值