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

6 篇文章 7 订阅

看了上一篇:
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 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_;

}

调用:

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 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;
    }
}

调用:

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

展示:
这里写图片描述

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

扫码关注公众号“伟大程序猿的诞生“,更多干货新鲜文章等着你~

公众号回复“资料获取”,获取更多干货哦~

有问题添加本人微信号“fenghuokeji996” 或扫描博客导航栏本人二维码

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值