Android的JNI【实战教程】3⃣️--Java调用C代码

来源:互联网 发布:win10设置元素数据出错 编辑:程序博客网 时间:2024/06/11 20:03

看了上一篇:
http://blog.csdn.net/github_33304260/article/details/62891083
我们应该已经可以构建NDK工程了 ,
接下来让我们看看Java调用C代码:

Java调用C代码执行加法操作

java代码:

    /**     * 通过JNI简单进行整形加法操作     * @param a     * @param b     * @return     */    public static native int addInt(int a, int b);

.h代码:

/* * Class:     com_libin_factory_ndk_NDK * Method:    addInt * Signature: (II)I */JNIEXPORT jint JNICALL Java_com_libin_factory_ndk_NDK_addInt  (JNIEnv *, jclass, jint, jint);

c++代码:

JNIEXPORT jint JNICALL Java_com_libin_factory_ndk_NDK_addInt        (JNIEnv *env, jclass type, jint a, jint b) {    return a + b;}

调用:

Toast.makeText(JNIActivity.this, "相加结果:" + NDK.addInt(10, 2), Toast.LENGTH_SHORT).show();

展示:
这里写图片描述

说明:

Java_全类名_方法名
Java_com_libin_factory_ndk_NDK_addInt

Java调用C代码执行字符串拼接操作

java代码:

    /**     * 通过JNI简单进行字符串拼接操作     * @param s     * @return     */    public static native String addString(String s);

.h代码:

/* * Class:     com_libin_factory_ndk_NDK * Method:    addString * Signature: (Ljava/lang/String;)Ljava/lang/String; */JNIEXPORT jstring JNICALL Java_com_libin_factory_ndk_NDK_addString  (JNIEnv *, jclass, jstring);

c++代码:

/** * 通过JNI简单进行字符串拼接操作 * @param s * @return */JNIEXPORT jstring JNICALL Java_com_libin_factory_ndk_NDK_addString        (JNIEnv *env, jclass type, jstring s_) {    char *text = jstringToChar(env, s_);    char temp[20] = "    /  I am from c";    strcat(text, temp);    return charToString(env, text);}

下面两个是工具类

/** * String转换为Char * @param env * @param jstr * @return */char* jstringToChar(JNIEnv* env, jstring jstr) {    char* rtn = NULL;    jclass clsstring = env->FindClass("java/lang/String");    jstring strencode = env->NewStringUTF("utf-8");    jmethodID mid = env->GetMethodID(clsstring, "getBytes", "(Ljava/lang/String;)[B");    jbyteArray barr= (jbyteArray)env->CallObjectMethod(jstr, mid, strencode);    jsize alen = env->GetArrayLength(barr);    jbyte* ba = env->GetByteArrayElements(barr, JNI_FALSE);    if (alen > 0)    {        rtn = (char*)malloc(alen + 1);        memcpy(rtn, ba, alen);        rtn[alen] = 0;    }    env->ReleaseByteArrayElements(barr, ba, 0);    return rtn;}/** * Char转换成String * @param env * @param chr * @return */jstring charToString(JNIEnv *env, const char *chr){    //LOGI("charToString: %s\n", chr);    jclass strClass = env->FindClass("java/lang/String");    jmethodID strConstruct = env->GetMethodID(strClass, "<init>", "([BLjava/lang/String;)V");    jbyteArray bytes = env->NewByteArray(strlen(chr));    env->SetByteArrayRegion(bytes, 0, strlen(chr), (jbyte*)chr);    jstring encoding = env->NewStringUTF("utf-8");    return (jstring)env->NewObject(strClass, strConstruct, bytes, encoding);}

调用:

Toast.makeText(JNIActivity.this, "JNI结果 :" + NDK.addString("I am From Java"), Toast.LENGTH_SHORT).show();

展示:
这里写图片描述

Java调用C代码执行每个元素加上10

java代码:

    /**     * 让C代码给你每个元素加上10     * @param intArray     * @return     */    public static native int[] increaseArrayEles(int[] intArray);

.h代码:

/* * Class:     com_libin_factory_ndk_NDK * Method:    increaseArrayEles * Signature: ([I)[I */JNIEXPORT jintArray JNICALL Java_com_libin_factory_ndk_NDK_increaseArrayEles  (JNIEnv *, jclass, jintArray);

c++代码:

/*** 让C代码给你每个元素加上10* @param intArray* @return*/JNIEXPORT jintArray JNICALLJava_com_libin_factory_ndk_NDK_increaseArrayEles(JNIEnv *env, jclass type, jintArray intArray_) {    //得到数组的长度    jsize size = env->GetArrayLength(intArray_);    //得到数组元素    jint *array = env->GetIntArrayElements(intArray_, JNI_FALSE); //JNI_FALSE同一份 不开辟新空间    //遍历数组给每个元素加上10    for (int i = 0; i < size; i++) {        *(array + i) += 10;        LOGE("array %d = %d", i, *(array + i));    }    env->ReleaseIntArrayElements(intArray_, array, 0);    //返回结果    return intArray_;}

调用:

int a[] = {1,2,3,4,5,6,7};int[] ints = NDK.increaseArrayEles(a);for (int i = 0 ; i< ints.length;i++){     Logger.e(a[i]+"");}

展示:
这里写图片描述

Java调用C代码执行检测密码是否正确

java代码:

    /**     * 应用:检测密码是否正确,正确返回200,错误返回400     * @param pwd     * @return     */    public static native int checkPwd(String pwd);

.h代码:

/* * Class:     com_libin_factory_ndk_NDK * Method:    checkPwd * Signature: (Ljava/lang/String;)I */JNIEXPORT jint JNICALL Java_com_libin_factory_ndk_NDK_checkPwd  (JNIEnv *, jclass, jstring);

c++代码:

/*** 应用:检测密码是否正确,正确返回200,错误返回400* @param pwd* @return*/JNIEXPORT jint JNICALLJava_com_libin_factory_ndk_NDK_checkPwd(JNIEnv *env, jclass type, jstring pwd_) {    //假设服务器密码123456    char *otigin = "123456";    char *fromUser = jstringToChar(env, pwd_);    //函数比较字符串是否相同    int code = strcmp(otigin, fromUser);    if (code == 0) {        return 200;    } else {        return 400;    }}

调用:

Toast.makeText(JNIActivity.this,"密码校验"+ NDK.checkPwd("123456"), Toast.LENGTH_SHORT).show();

展示:
这里写图片描述

下面我们可以在看看 C调用java:
http://blog.csdn.net/github_33304260/article/details/71213921

8 0