前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Android的JNI【实战教程】3⃣️--Java调用C代码

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

作者头像
先知先觉
发布2019-01-21 15:26:26
9310
发布2019-01-21 15:26:26
举报

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

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

java代码:

代码语言:javascript
复制
    /**
     * 通过JNI简单进行整形加法操作
     * @param a
     * @param b
     * @return
     */
    public static native int addInt(int a, int b);

.h代码:

代码语言:javascript
复制
/*
 * 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++代码:

代码语言:javascript
复制
JNIEXPORT jint JNICALL Java_com_libin_factory_ndk_NDK_addInt
        (JNIEnv *env, jclass type, jint a, jint b) {

    return a + b;
}

调用:

代码语言:javascript
复制
Toast.makeText(JNIActivity.this, "相加结果:" + NDK.addInt(10, 2), Toast.LENGTH_SHORT).show();

展示:

这里写图片描述
这里写图片描述

说明:

Java_全类名_方法名 Java_com_libin_factory_ndk_NDK_addInt

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

java代码:

代码语言:javascript
复制
    /**
     * 通过JNI简单进行字符串拼接操作
     * @param s
     * @return
     */
    public static native String addString(String s);

.h代码:

代码语言:javascript
复制
/*
 * 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++代码:

代码语言:javascript
复制
/**
 * 通过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);

}

下面两个是工具类

代码语言:javascript
复制
/**
 * 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);
}

调用:

代码语言:javascript
复制
Toast.makeText(JNIActivity.this, "JNI结果 :" + NDK.addString("I am From Java"), Toast.LENGTH_SHORT).show();

展示:

这里写图片描述
这里写图片描述

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

java代码:

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

.h代码:

代码语言:javascript
复制
/*
 * 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++代码:

代码语言:javascript
复制
/**
* 让C代码给你每个元素加上10
* @param intArray
* @return
*/
JNIEXPORT jintArray JNICALL
Java_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_;

}

调用:

代码语言:javascript
复制
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代码:

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

.h代码:

代码语言:javascript
复制
/*
 * 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++代码:

代码语言:javascript
复制
/**
* 应用:检测密码是否正确,正确返回200,错误返回400
* @param pwd
* @return
*/
JNIEXPORT jint JNICALL
Java_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;
    }
}

调用:

代码语言:javascript
复制
Toast.makeText(JNIActivity.this,"密码校验"+ NDK.checkPwd("123456"), Toast.LENGTH_SHORT).show();

展示:

这里写图片描述
这里写图片描述

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

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2017年03月29日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Java调用C代码执行加法操作
  • Java调用C代码执行字符串拼接操作
  • Java调用C代码执行每个元素加上10
  • Java调用C代码执行检测密码是否正确
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档