JNI由浅入深_10_JNI 综合开发

来源:互联网 发布:北京大学数据可视化 编辑:程序博客网 时间:2024/06/05 10:05

1、使用ndk-build时如果找不到某个类,可以使用下面两种方法解决:

1、1 进入src目录

D:\project3\JNIAndroid\src>set classpath=D:\project3\JNIAndroid\src

1、2 设置classpath
classpath    .;%JAVA_HOME%\lib\dt.jar;%JAVA_HOME%\tools.jar;E:\developLib\android\platforms\android-8\android.jar

2、基础类

ublic class NativeModule {    public native int testArg(int i, boolean b, char c, double d);    public native byte[] testByte(byte[] b);    public native String[] testString(String s, String[] sarr);    public native int setInfo(MyInfo info);    public native MyInfo getInfo();    static {       System.loadLibrary("NativeModule");    }}

//其中MyInfo类定义如下:public class Record {    int id;    String name;    byte[] data;}public class MyInfo {    public boolean b;    public char c;    public double d;    public int i;    public byte[] array;    public String s;    public Record rec;}

c 结构体定义

typedef struct{    int id;    char name[255];    char data[255];}Record; typedef struct{    BOOL b;    char c;    double d;    int i;    char arr[255];    char sz[255];    Record rec;}MyInfo;

3、编写C库

 3.1) Java与C不同类型参数转换实例

//不同类型参数处理JNIEXPORT jintJNICALL Java_com_jinhill_util_NativeModule_testArg  (JNIEnv *env, jobject jo, jint ji, jbooleanjb,  jchar jc, jdouble jd){         //获取jint型值         int i = ji;         //获取jboolean型值         BOOL b = jb;         //获取jdouble型值         double d = jd;         //获取jchar型值,Java的char两字节         char ch[5] = {0};         int size = 0;         size = WideCharToMultiByte(CP_ACP,NULL, (LPCWSTR)&jc, -1, ch, 5, NULL, FALSE);         if(size <= 0) {                   return -1;         }         Trace("ji=%d,jb=%d,jc=%s,jd=%lf",i, b, ch, d);         return 0;}

 3.2) Java byte与C char数组类型数组转换实例

//btye数组处理,形参作为输入或输出,返回btye数组JNIEXPORTjbyteArray JNICALL Java_com_jinhill_util_NativeModule_testByte  (JNIEnv *env, jobject jo, jbyteArray jbArr){         char chTmp[] = "Hello JNI!";         int nTmpLen = strlen(chTmp);         //获取jbyteArray         char *chArr = (char*)env->GetByteArrayElements(jbArr,0);         //获取jbyteArray长度         int nArrLen = env->GetArrayLength(jbArr);         char *szStrBuf =(char*)malloc(nArrLen*2+10);         memset(szStrBuf, 0, nArrLen*2+10);         Bytes2String(chArr, nArrLen, szStrBuf,nArrLen*2+10);         Trace("jbArr=%s", szStrBuf);         //将jbArr作为输出形参         memset(chArr, 0, nArrLen);         memcpy(chArr, chTmp, nTmpLen);         //返回jbyteArray         jbyteArray jarrRV =env->NewByteArray(nTmpLen);     jbyte *jby =env->GetByteArrayElements(jarrRV, 0);         memcpy(jby, chTmp, strlen(chTmp));    env->SetByteArrayRegion(jarrRV, 0,nTmpLen, jby);          return jarrRV;}

 3.3)   Java String与C char数组类型转换实例

 
//String 和String[]处理JNIEXPORTjobjectArray JNICALL Java_com_jinhill_util_NativeModule_testString  (JNIEnv *env, jobject jo, jstring jstr,jobjectArray joarr){         int i = 0;         char chTmp[50] = {0};         //获取jstring值         const char* pszStr = (char*)env->GetStringUTFChars(jstr, 0);         Trace("jstr=%s", pszStr);         //获取jobjectArray值         int nArrLen =env->GetArrayLength(joarr);         Trace("joarr len=%d",nArrLen);         for(i=0; i<nArrLen; i++) {                   jstring js =(jstring)env->GetObjectArrayElement(joarr, i);                   const char* psz = (char*)env->GetStringUTFChars(js, 0);                   Trace("joarr[%d]=%s",i, psz);         }         //将joarr作为输出形参         jstring jstrTmp = NULL;         for(i=0; i<nArrLen; i++) {                   sprintf(chTmp, "No.%dHello JNI!", i);                   jstrTmp =env->NewStringUTF(chTmp);                   env->SetObjectArrayElement(joarr,i, jstrTmp);                   env->DeleteLocalRef(jstrTmp);         }         //返回jobjectArray         jclass jstrCls =env->FindClass("Ljava/lang/String;");         jobjectArray jstrArray =env->NewObjectArray(2, jstrCls, NULL);         for(i=0; i<2; i++) {                   sprintf(chTmp, "No. %dReturn JNI!", i);                   jstrTmp =env->NewStringUTF(chTmp);                   env->SetObjectArrayElement(jstrArray,i, jstrTmp);                   env->DeleteLocalRef(jstrTmp);         }         return jstrArray;}

 3.4)   Java 类与C结构体类型转换实例

JNIEXPORT jint JNICALL Java_com_jinhill_util_NativeModule_setInfo  (JNIEnv *env, jobject jo, jobject jobj){    char chHexTmp[512] = {0};    //将Java类转换成C结构体    MyInfo mi;    //获取Java中的实例类Record    jclass jcRec = env->FindClass("com/jinhill/util/Record");    //int id    jfieldID jfid = env->GetFieldID(jcRec, "id", "I");    //String name    jfieldID jfname = env->GetFieldID(jcRec, "name", "Ljava/lang/String;");    //byte[] data;    jfieldID jfdata = env->GetFieldID(jcRec, "data", "[B");    //获取Java中的实例类MyInfo    jclass jcInfo = env->FindClass("com/jinhill/util/MyInfo");    //获取类中每一个变量的定义    //boolean b    jfieldID jfb = env->GetFieldID(jcInfo, "b", "Z");    //char c    jfieldID jfc = env->GetFieldID(jcInfo, "c", "C");    //double d    jfieldID jfd = env->GetFieldID(jcInfo, "d", "D");    //int i    jfieldID jfi = env->GetFieldID(jcInfo, "i", "I");    //byte[] array    jfieldID jfa = env->GetFieldID(jcInfo, "array", "[B");    //String s    jfieldID jfs = env->GetFieldID(jcInfo, "s", "Ljava/lang/String;");    //Record rec;    jfieldID jfrec = env->GetFieldID(jcInfo, "rec", "Lcom/jinhill/util/Record;");     //获取实例的变量b的值    mi.b = env->GetBooleanField(jobj, jfb);    //获取实例的变量c的值    jchar jc = env->GetCharField(jobj, jfc);    char ch[5] = {0};    int size = 0;    size = WideCharToMultiByte(CP_ACP, NULL, (LPCWSTR)&jc, -1, ch, 5, NULL, FALSE);    mi.c = ch[0];    //获取实例的变量d的值    mi.d = env->GetDoubleField(jobj, jfd);    //获取实例的变量i的值    mi.i = env->GetIntField(jobj, jfi);    //获取实例的变量array的值    jbyteArray ja = (jbyteArray)env->GetObjectField(jobj, jfa);    int  nArrLen = env->GetArrayLength(ja);    char *chArr = (char*)env->GetByteArrayElements(ja, 0);    memcpy(mi.arr, chArr, nArrLen);    //获取实例的变量s的值    jstring jstr = (jstring)env->GetObjectField(jobj, jfs);    const char* pszStr = (char*)env->GetStringUTFChars(jstr, 0);    strcpy(mi.sz, pszStr);     //获取Record对象    jobject joRec = env->GetObjectField(jobj, jfrec);    //获取Record对象id值    mi.rec.id = env->GetIntField(joRec, jfid);    Trace("mi.rec.id=%d",mi.rec.id);    //获取Record对象name值    jstring jstrn = (jstring)env->GetObjectField(joRec, jfname);    pszStr = (char*)env->GetStringUTFChars(jstrn, 0);    strcpy(mi.rec.name, pszStr);    //获取Record对象data值    jbyteArray jbd = (jbyteArray)env->GetObjectField(joRec, jfdata);    nArrLen = env->GetArrayLength(jbd);    chArr = (char*)env->GetByteArrayElements(jbd, 0);    memcpy(mi.rec.data, chArr, nArrLen);    //日志输出    Bytes2String(mi.arr, nArrLen, chHexTmp, sizeof(chHexTmp));    Trace("mi.arr=%s, mi.b=%d, mi.c=%c, mi.d=%lf, mi.i=%d, \n mi.sz=%s\n mi.rec.id=%d, mi.rec.name=%s", chHexTmp, mi.b, mi.c, mi.d, mi.i, mi.sz, mi.rec.id, mi.rec.name);     return 0;}

 3.5)   C结构体类型与Java 类转换实例 

 
JNIEXPORT jobject JNICALL Java_com_jinhill_util_NativeModule_getInfo  (JNIEnv *env, jobject jo){   wchar_t wStr[255] = {0};    char chTmp[] = "Hello JNI";    int nTmpLen = strlen(chTmp);    //将C结构体转换成Java类    MyInfo mi;    memcpy(mi.arr, chTmp, strlen(chTmp));    mi.b = TRUE;    mi.c = 'B';    mi.d = 2000.9;    mi.i = 8;    strcpy(mi.sz, "Hello World!");    mi.rec.id = 2011;    memcpy(mi.rec.data, "\x01\x02\x03\x04\x05\x06", 6);    strcpy(mi.rec.name, "My JNI");    //获取Java中的实例类Record    jclass jcRec = env->FindClass("com/jinhill/util/Record");    //int id    jfieldID jfid = env->GetFieldID(jcRec, "id", "I");    //String name    jfieldID jfname = env->GetFieldID(jcRec, "name", "Ljava/lang/String;");    //byte[] data;    jfieldID jfdata = env->GetFieldID(jcRec, "data", "[B");     //获取Java中的实例类    jclass jcInfo = env->FindClass("com/jinhill/util/MyInfo");    //获取类中每一个变量的定义    //boolean b    jfieldID jfb = env->GetFieldID(jcInfo, "b", "Z");    //char c    jfieldID jfc = env->GetFieldID(jcInfo, "c", "C");    //double d    jfieldID jfd = env->GetFieldID(jcInfo, "d", "D");    //int i    jfieldID jfi = env->GetFieldID(jcInfo, "i", "I");    //byte[] array    jfieldID jfa = env->GetFieldID(jcInfo, "array", "[B");    //String s    jfieldID jfs = env->GetFieldID(jcInfo, "s", "Ljava/lang/String;");    //Record rec;    jfieldID jfrec = env->GetFieldID(jcInfo, "rec", "Lcom/jinhill/util/Record;");     //创建新的对象    jobject joRec = env->AllocObject(jcRec);     env->SetIntField(joRec, jfid, mi.rec.id);     jstring jstrn = env->NewStringUTF(mi.rec.name);    env->SetObjectField(joRec, jfname, jstrn);     jbyteArray jbarr = env->NewByteArray(6);     jbyte *jb = env->GetByteArrayElements(jbarr, 0);    memcpy(jb, mi.rec.data, 6);    env->SetByteArrayRegion(jbarr, 0, 6, jb);    env->SetObjectField(joRec, jfdata, jbarr);    //创建新的对象    jobject joInfo = env->AllocObject(jcInfo);     //给类成员赋值    env->SetBooleanField(joInfo, jfb, mi.b);//  MultiByteToWideChar (CP_ACP, 0, mi.c, -1, wStr, 255);//  env->SetCharField(joInfo, jfc, (jchar)wStr);    env->SetCharField(joInfo, jfc, (jchar)mi.c);    env->SetDoubleField(joInfo, jfd, mi.d);    env->SetIntField(joInfo, jfi, mi.i);    jbyteArray jarr = env->NewByteArray(nTmpLen);     jbyte *jby = env->GetByteArrayElements(jarr, 0);    memcpy(jby, mi.arr, nTmpLen);    env->SetByteArrayRegion(jarr, 0, nTmpLen, jby);    env->SetObjectField(joInfo, jfa, jarr);    jstring jstrTmp = env->NewStringUTF(chTmp);    env->SetObjectField(joInfo, jfs, jstrTmp);    env->SetObjectField(joInfo, jfrec, joRec);    return joInfo;}

 3.6)   Java String与 C char数组转换时的中文问题

//将jstring类型转换成windows类型char* jstringToWindows( JNIEnv *env, jstring jstr ){<span style="white-space:pre"></span>int length = (env)->GetStringLength(jstr );<span style="white-space:pre"></span>const jchar* jcstr = (env)->GetStringChars(jstr, 0 );<span style="white-space:pre"></span>char* rtn = (char*)malloc( length*2+1 );<span style="white-space:pre"></span>int size = 0;<span style="white-space:pre"></span>size = WideCharToMultiByte( CP_ACP, 0, (LPCWSTR)jcstr, length,rtn,(length*2+1), NULL, NULL );<span style="white-space:pre"></span>if( size <= 0 )<span style="white-space:pre"></span>return NULL;<span style="white-space:pre"></span>(env)->ReleaseStringChars(jstr, jcstr );<span style="white-space:pre"></span>rtn[size] = 0;<span style="white-space:pre"></span>return rtn;}//将windows类型转换成jstring类型jstring WindowsTojstring( JNIEnv* env, char* str ){<span style="white-space:pre"></span>jstring rtn = 0;<span style="white-space:pre"></span>int slen = strlen(str);<span style="white-space:pre"></span>unsigned short * buffer = 0;<span style="white-space:pre"></span>if( slen == 0 )<span style="white-space:pre"></span>rtn = (env)->NewStringUTF(str );<span style="white-space:pre"></span>else<span style="white-space:pre"></span>{<span style="white-space:pre"></span>int length = MultiByteToWideChar( CP_ACP, 0, (LPCSTR)str, slen, NULL, 0 );<span style="white-space:pre"></span>buffer = (unsigned short *)malloc( length*2 + 1 );<span style="white-space:pre"></span>if( MultiByteToWideChar( CP_ACP, 0, (LPCSTR)str, slen, (LPWSTR)buffer, length )>0 )<span style="white-space:pre"></span>rtn = (env)->NewString( (jchar*)buffer, length );<span style="white-space:pre"></span>}<span style="white-space:pre"></span>if( buffer )<span style="white-space:pre"></span>free( buffer );<span style="white-space:pre"></span>return rtn;}


0 0
原创粉丝点击