实现简单的NDK操作

在这里有个小技巧,在每次创建 Cpp 方法的时候,都要这样写:

Java_top_jowanxu_jnidemo_MainActivity_stringFromJNI

当你方法多的时候,要改名的时候,就很麻烦了,所以我们可以将前面共有的提取出来,使用宏定义来实现。

首先,创建一个头文件,并且在里面定义宏:

// file name package-func-name
#ifndef JNIDEMO_PACKAGE_FUNC_NAME_H
#define JNIDEMO_PACKAGE_FUNC_NAME_H

#define PKFUNC(name) Java_top_jowanxu_jnidemo_##name

#endif //JNIDEMO_PACKAGE_FUNC_NAME_H

然后在我们需要使用的时候,先导入头文件,然后使用方法:

extern "C"
JNIEXPORT jstring JNICALL PKFUNC(MainActivity_stringFromJNI)(
        JNIEnv *env,
        jobject thiz) {
    return env->NewStringUTF("Hello from JNI !");
}

这样就很方便了,在这里感谢李哥提供的帮助。

开始

在这里先介绍Java类型对应Jni层数据描述的关系:

基本类型:

Java类型JNI类型C/C++类型大小
booleanjbooleanunsigned char无符号 8位
bytejbytechar有符号 8位
charjcharunsigned short无符号 16位
shortjshortshort有符号 16位
intjintint有符号 32位
longjlonglong long有符号 64位
floatjfloatfloat32位
doublejdoubledouble64位

引用类型:

Java类型JNI类型
voidvoid
java.lang.Classjclass
java.lang.Throwablejthrowable
java.lang.Stringjclass
Objectjobject
type[]jtypeArray

type表示基本类型和Object。

我们来写一个最大公约数的方法,先定义一个方法:

external fun gcd(m: Int, n: Int): Int

然后在Cpp里面创建对应的方法:

#include "package-func-name.h"

extern "C"
JNIEXPORT jint JNICALL PKFUNC(MainActivity_gcd)(JNIEnv *env, jobject, jint m, jint n) {
    jint c;
    for (; m > 0;) {
        c = n % m;
        n = m;
        m = c;
    }
    return n;
}

在Cpp里面定义的函数的第一个参数都是 JNIEnv *env ,这是什么东西呢?

JNIEnv 就是 JNI Environmont ,JNI的环境。

再举个例子,当我们用一个引用类型参数的时候,比如一个int数组:

extern "C"
JNIEXPORT jint JNICALL PKFUNC(MainActivity_gcd)(JNIEnv *env, jobject, jintArray _data) {

}

_data 其实是一个指向 JVM 里面对应该数组的内存的指针,你可以通过它获取数组的元素等操作,但它本身和数组无关,所以你不能对他进行操作。

只能通过 JNIEnv 指针来获取数组本身的指针,然后进行各种操作。

extern "C"
JNIEXPORT void JNICALL PKFUNC(MainActivity_getArray)(
        JNIEnv *env,
        jobject,
        jintArray _data) {
    jint *data = env->GetIntArrayElements(_data, NULL);
    for (int i = 0; i < env->GetArrayLength(_data); ++i) {
        LOGE("------:%d", data[i]);
    }
    env->ReleaseIntArrayElements(_data, data, JNI_ABORT);
    // ReleaseIntArrayElements释放资源:
    // JNI_ABORT表示不复制,释放资源
    // JNI_OK表示复制回到JVM中,释放资源
    // JNI_COMMIT表示复制,不释放资源
}

打印内容:

E/CUSTOMER_NDK_JNI: ------:1
E/CUSTOMER_NDK_JNI: ------:2
E/CUSTOMER_NDK_JNI: ------:3
E/CUSTOMER_NDK_JNI: ------:4
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值