02-JNI-java相互调用

来源:互联网 发布:查产品编号的软件 编辑:程序博客网 时间:2024/06/14 22:24

1.java传递数据给C

第一步:

在java中声明函数:    public native int add(int x,int y);运行Android Tools工具,生成含有.cpp文件的/jni/  目录 

第二步:

利用dos命令生成C的函数名

添加到src/jni/javatoc.c  文件中在函数中实现 数据操作// 用c进行加法运算,返回给java
JNIEXPORT jint JNICALL Java_com_uu_javatoc_JNI_add      (JNIEnv * env, jobject clazz, jint x, jint y){        return x+y;    }

第三步:

在相应的位置调用JNI函数
public void stringclick(View v){            String hello = jni.sayHelloInc("123456");            Toast.makeText(getApplicationContext(), hello, 0).show();        }

2.在C代码中使用logcat

Android.mk文件增加以下内容

LOCAL_LDLIBS += -llog

C代码中增加以下内容

    #include <android/log.h>    #define LOG_TAG "System.out"    #define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)    #define LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)

C函数中使用:

LOGD("length = %d",length);

3.JNI操作中常用到的 C转换函数(方法)

  • 得到数组的长度
     JArray 为jNI中c的自定义数据jsize length = (*env)->GetArrayLength(env,jArray);
  • 得到数组指针
int* arrayPointer = (*env)->GetIntArrayElements(env,jArray,NULL);
  • 得到java 的字节码文件
jclass claz = (*env)->FindClass(env, "com/uu/ctojava/JNI");
  • 得到java 类中的函数ID
jmethodID methodID = (*env)->GetMethodID(env, claz, "helloFromJava", "()V");
  • 调用java 类中的函数
//无返回值        (*env)->CallVoidMethod(env, clazz, methodID,...);        有返回值        (*env)->CallIntMethod(env, clazz, methodID, x, y);        LOGD("sum = %d", sum)
  • 将char* 转换成 jstring
jstring result =(*env)->NewStringUTF(env,"hello from java");
注意:第二个参数不能含有中文,虽为UTF-8 ,但确实不能,否则报错

3.jstring转换成char* 分析

  • 函数如下所示:
    个人分析,转载请注明出处
char* _JString2CStr(JNIEnv* env, jstring jstr) {             char* rtn = NULL;             //得到String 的字节码文件             jclass clsstring = (*env)->FindClass(env, "java/lang/String");             //将“GB2312” 转换成    jstring类型的数据             jstring strencode = (*env)->NewStringUTF(env,"GB2312");             //获得java 中 String的getBytes 方法             jmethodID mid = (*env)->GetMethodID(env, clsstring, "getBytes", "(Ljava/lang/String;)[B");             //将jstring 类型的jstr    转换成  jbyteArray 类型的数组             jbyteArray barr = (jbyteArray)    (*env)->CallObjectMethod(env, jstr, mid, strencode); // String .getByte("GB2312");             //得到  字符数组(barr) 的 长度             jsize alen = (*env)->GetArrayLength(env, barr);             //得到  字符数组(barr) 的 指针             jbyte* ba = (*env)->GetByteArrayElements(env, barr, JNI_FALSE);             if(alen > 0) {                //为char *  类型的 rtn 开辟内存空间                rtn = (char*)malloc(alen+1); //"\0"                //将 字符数组   copy  到rtn   中                memcpy(rtn, ba, alen);                //0 返回                rtn[alen]=0;             }             (*env)->ReleaseByteArrayElements(env, barr, ba,0);             return rtn;        }
0 0
原创粉丝点击