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

android jni常用数据类型的记录

2015-05-18 13:51 281 查看
感觉最近工作中,经常需要用到jni,jni是项目开发中经常用到的一种机制,比较便捷,主要目的是,实现应用层调用底层驱动层的方法。

最基本的一些关于jni的知识,就不再这边讲述,这边主要记录一些常用的代码架构。

1. 主要的代码基本框架:

jni 我这边主要有两种经常用到的形式,形式一:

<span style="font-size:14px;">#include <jni.h>
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <sys/time.h>
#include <sys/stat.h>
#include <termios.h>
#include <sys/types.h>
#include <cutils/properties.h>
#include <utils/Log.h>
#include <pthread.h>

JNIEXPORT jint JNICALL Java_com_android_device_example_write(JNIEnv *env,
jobject thiz,jbyteArray data) {
int ret = 0;

jbyte *sdata = (*env)->GetByteArrayElements(env, data, NULL);

int len =  (*env)->GetArrayLength(env,data);
ret = serial_write_data((char*)sdata,len);

(*env)->ReleaseByteArrayElements(env, data, sdata, 0);
return ret;
}</span>


形式二:
#define LOG_TAG "RfidSerialPort"
#include "utils/Log.h"
//#include<ALog.h>
#include     <stdio.h>
#include     <stdlib.h>
#include     <unistd.h>
#include     <sys/types.h>
#include     <sys/stat.h>
#include     <fcntl.h>
#include     <termios.h>
#include     <errno.h>
#include     <string.h>
#include 		 <jni.h>
#include <ctype.h>

jint <span style="font-family: Arial, Helvetica, sans-serif; font-size: 14px;">example_write</span><span style="font-family: Arial, Helvetica, sans-serif;">(JNIEnv *env, jobject thiz,</span>
jint ENum1,
jstring  WriteEPC)
{

const char* jWriteEPC = env->GetStringUTFChars(WriteEPC,NULL);

env->ReleaseStringUTFChars(WriteEPC, jWriteEPC);

return result ;
}

static JNINativeMethod gMethods[] = {
{"<span style="font-family: Arial, Helvetica, sans-serif; font-size: 14px;">example_write</span>", "(ILjava/lang/String;)I" , (void*)<span style="font-family: Arial, Helvetica, sans-serif; font-size: 14px;">example_write</span>
},

};

/*
* Register several native methods for one class.
*/

static const char *classPathName = "xx/xx";

static int registerNatives(JNIEnv* env)
{
jclass clazz;

clazz = env->FindClass(classPathName);
if (clazz == NULL) {
LOGE("Native registration unable to find class '%s'", classPathName);
return JNI_FALSE;
}else{
LOGI("find class sucess");
}
if (env->RegisterNatives(clazz, gMethods, sizeof(gMethods)/sizeof(gMethods[0])) < 0) {
LOGE("RegisterNatives failed for '%s'", classPathName);
return JNI_FALSE;
}

return JNI_TRUE;
}

/*
*
**This is called by the VM when the shared library is first loaded.
*
*/

jint JNI_OnLoad(JavaVM* vm, void* reserved)
{
jint result = -1;
JNIEnv* env = NULL;

LOGI("JNI_OnLoad");

if (vm->GetEnv((void **)&env, JNI_VERSION_1_4) != JNI_OK) {
LOGE("ERROR: GetEnv failed");
goto bail;
}

if (registerNatives(env) != JNI_TRUE) {
LOGE("ERROR: registerNatives failed");
goto bail;
}

result = JNI_VERSION_1_4;

bail:
return result;
}


2. 一些常用的数据类型的传参与转换方法:

2.1 Object 方法,对java返回ArrayList的类型。

jobject Object(JNIEnv *env, jobject thiz)
{

jclass list_cls = env->FindClass("java/util/ArrayList");

if(list_cls == NULL)
{
return NULL;
}

jmethodID list_costruct = env->GetMethodID(list_cls , "<init>","()V");

if(list_costruct ==NULL)
{

return NULL;
}

jobject list_obj = env->NewObject(list_cls , list_costruct);
if(list_obj ==NULL)
{
return NULL;
}

jmethodID list_add  = env->GetMethodID(list_cls,"add","(Ljava/lang/Object;)Z");
if(list_add ==NULL)
{

return NULL;
}

unsigned char uid[20];

unsigned char *arr =NULL;
unsigned char out_arr[64];

for(int i = 0 ; i < CardNum; i++)
{

memset(uid,0x00,20);

arr= (unsigned char *)malloc((uidlen)*sizeof(unsigned char));
if(arr==NULL)
{
LOGE("malloc the arr err");
return NULL;
}

jstring encoding = env->NewStringUTF((const char*)out_arr);
env->CallBooleanMethod(list_obj , list_add ,encoding);

free(arr);

}

return list_obj ;

}
<pre name="code" class="cpp"><pre name="code" class="cpp">static JNINativeMethod gMethods[] = {
{"<span style="font-family: Arial, Helvetica, sans-serif;">Object</span>", "()Ljava/util/ArrayList;" , (void*)<span style="font-family: Arial, Helvetica, sans-serif;">Object</span>},
};






2.2 jstring、jbytearray的例子:

jint Jstring(JNIEnv *env, jobject thiz,
jint ENum1,
jstring  WriteEPC)
{

const char* jWriteEPC = env->GetStringUTFChars(WriteEPC,NULL);

env->ReleaseStringUTFChars(WriteEPC, jWriteEPC);

return result ;
}
static JNINativeMethod gMethods[] = {

{"<span style="font-family: Arial, Helvetica, sans-serif;">Jstring</span>", "(ILjava/lang/String;)I" , (void*)<span style="font-family: Arial, Helvetica, sans-serif;">Jstring</span>},

};


2.3 C和java 中常用到的数据类型的转换

2.3.1 C中string 与 16进制数的转化

static void HexToStr(unsigned char *pbDest, unsigned char *pbSrc, int nLen)
{
char	ddl,ddh;
int i;

for (i=0; i<nLen; i++)
{
ddh = 48 + pbSrc[i] / 16;
ddl = 48 + pbSrc[i] % 16;
if (ddh > 57) ddh = ddh + 7;
if (ddl > 57) ddl = ddl + 7;
pbDest[i*2] = ddh;
pbDest[i*2+1] = ddl;
}

pbDest[nLen*2] = '\0';
}

static void StrToHex(unsigned char *pbDest, unsigned char *pbSrc, int nLen)
{
char h1,h2;
unsigned char s1,s2;
int i;

for (i=0; i<nLen; i++)
{
h1 = pbSrc[2*i];
h2 = pbSrc[2*i+1];

s1 = toupper(h1) - 0x30;
if (s1 > 9)
s1 -= 7;

s2 = toupper(h2) - 0x30;
if (s2 > 9)
s2 -= 7;

pbDest[i] = s1*16 + s2;
}
}


2.3.2 JAVA 中string 与 byte 中转化:

private static String bytesToHexString(byte[] src) {
StringBuilder stringBuilder = new StringBuilder("");
if (src == null || src.length <= 0) {
return null;
}
for (int i = 0; i < src.length; i++) {
int v = src[i] & 0xFF;
String hv = Integer.toHexString(v);
if (hv.length() == 1){
hv = '0' + hv;
}
stringBuilder.append(hv);
}
return stringBuilder.toString();
}

private static String bytesToHexString(byte[] src, int offset, int length) {
StringBuilder stringBuilder = new StringBuilder("");
if (src == null || src.length <= 0) {
return null;
}
for (int i = offset; i < length; i++) {
int v = src[i] & 0xFF;
String hv = Integer.toHexString(v);
if (hv.length() == 1) {
stringBuilder.append(0);
}
stringBuilder.append(hv);
}
return stringBuilder.toString();
}

private static byte[] hexStringToBytes(String hexString) {
if (hexString == null || hexString.equals("")) {
return null;
}
hexString = hexString.toUpperCase();
int length = hexString.length() /2;
char[] hexChars = hexString.toCharArray();
// Log.d(TAG, "hexChars.len=" + hexChars.length + "hexString.len = " + hexString.length ());
byte[] d = new byte[length];
for (int i = 0; i < length; i++) {
int pos = i * 2;
d[i] = (byte) (charToByte(hexChars[pos]) << 4 | charToByte(hexChars[pos + 1]));
}
return d;
}
private static byte charToByte(char c) {
return (byte) "0123456789ABCDEF".indexOf(c);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: