JNI 简单语法

java——JNI———-C
JNI相当于是翻译,将java类型的数据翻译为c能够识别的类型和
将c类型的数据翻译为java能够识别的类型

1、JNI对基本数据类型的处理

基本数据类型里面的值都可以直接返回得到

基本数据类型有哪些:
也就是java的八大基本类型
byte short int long
float double
boolean char

示例:jint ==int

2、JNI对复杂类型数据类型的处理

复杂类型有哪些:

这里只对其中比较常见的进行了处理,主要是字符串和数组两种
基本的操作样式
java——–jni———-c

在jni里面 通过env->New得到的类型是java的相关类型
通过env->Get得到的类型是c的相关类型

通过Get得到的c的相关类型 ,需要在得到数据之后Release掉

1)、对字符串的处理
java —-jni ——-c

JNIEXPORT void JNICALL Java_com_tjstudy_jnidemo_Jni_getString
        (JNIEnv * env, jclass jcs,jstring str){
    //1、jstring 转c
    // 将jstring类型的str转换为c能够识别的类型
    char *chars = (char *) env->GetStringUTFChars(str, JNI_FALSE);
    //这个chars c就能够使用了
    //释放资源
    env->ReleaseStringUTFChars(str,chars);




    //2、c转jstring
    jstring  jtr = env->NewStringUTF(chars);
}

demo:
场景,在android端写一段字符串,经过jni 返回 hello 这个字符串

JNIEXPORT jstring JNICALL Java_com_tjstudy_jnidemo_Jni_getbackString
        (JNIEnv *env, jclass jcs, jstring jstr) {
    //需要处理jstr  在jstr前面加上 hello
    //1、需要将其变成c的格式
    char *cstr = (char *) env->GetStringUTFChars(jstr, JNI_FALSE);
    char buf1[1024];
    //指针是指向某一个位置  这里将该位置设置为空 则表示该位置实质上是不存在的
    //简单来说  要存储值,就要有存储值得那个位置  这里没有指定位置 所以是错的
    //char *buf1 = NULL;
    sprintf(buf1, "hello %s", cstr);
    //memset(buf1, '0', 1024);
    env->ReleaseStringUTFChars(jstr, cstr);
    return env->NewStringUTF(buf1);
}

使用
env->GetStringUTFRegion(jstr, 0, len, buf + 7); 对字符串的操作

JNIEXPORT jstring JNICALL Java_com_tjstudy_jnidemo_Jni_getbackString
        (JNIEnv *env, jclass jcs, jstring jstr) {
    jsize len = env->GetStringLength(jstr);
    char buf[128] = {"hello 12"};
    //char *pBuf = buf+7;
    //*pBuf表示的是指针指向buf的第7个位置
    //也就是说 pBuf也是buf的一部分了  对pBuf的修改buf也会修改
    env->GetStringUTFRegion(jstr, 0, len, buf + 7);
    //将长度为len的jstr 复制到buf里面的第7个位置后面 可以直接写pBuf
    return env->NewStringUTF(buf);
}

2)、对数组的处理

JNIEXPORT jint JNICALL Java_com_tjstudy_jnidemo_Jni_sumArray
(JNIEnv *env, jclass jcs, jintArray jarray) {
        //需实现功能:计算数组里面的数值的和
        //jarray是java类型能够识别的 需要转换成c能够识别的数组
        //1、需要创建一个c的数组 大小和java的相同------获取java的数组的长度
        int j_len = env->GetArrayLength(jarray);
        //2、创建同等长度的数组
        //c要的是字节数
        jint *carray = (jint *) malloc(sizeof(jint) * j_len);
        //初始化缓冲区
        memset(carray,0,sizeof(jint)*j_len);//不知道为什么要 不要也正常
        //3、拷贝数组
        env->GetIntArrayRegion(jarray, 0, j_len, carray);
        int sum = 0;
        for (int i = 0; i < j_len; i++) {
        sum += i;
    }
    free(carray);
    return sum;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
JNI(Java Native Interface)是Java平台的一部分,它允许Java代码与本地代码(如C、C++等)进行交互。编写JNI需要使用C或C++编写本地方法,并使用Java Native Development Kit (JDK)提供的工具将其编译为共享库。以下是一个简单JNI示例: 1. 创建Java类 首先,我们需要创建一个Java类,其中包含本地方法的声明。例如,我们创建一个名为NativeTest的类,其中包含一个名为getString的本地方法: ``` public class NativeTest { public native String getString(); } ``` 2. 编写本地方法 接下来,我们需要在C/C++中编写本地方法。我们使用Java中的方法签名来声明本地方法。在本例中,我们使用以下方法签名声明getString方法: ``` JNIEXPORT jstring JNICALL Java_NativeTest_getString(JNIEnv *env, jobject obj) { return (*env)->NewStringUTF(env, "Hello from JNI!"); } ``` 该方法将返回一个字符串“Hello from JNI!”。 3. 生成共享库 接下来,我们需要使用JDK提供的工具将本地方法编译为共享库。我们可以使用命令行工具或构建工具(如Gradle)来执行此操作。在这里,我们将使用命令行工具。 首先,我们需要在本地方法文件夹中创建一个名为Android.mk的文件。该文件将告诉Android NDK如何构建共享库。例如: ``` LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE := native-lib LOCAL_SRC_FILES := NativeTest.c include $(BUILD_SHARED_LIBRARY) ``` 在此示例中,我们将共享库命名为“native-lib”,并指定一个本地方法文件“NativeTest.c”。 接下来,我们需要创建一个名为Application.mk的文件,该文件将指定构建共享库所需的平台和ABI。例如: ``` APP_ABI := all ``` 在这里,我们将构建所有平台和ABI的共享库。 现在,我们可以在命令行中使用以下命令构建共享库: ``` ndk-build ``` 4. 在Java中加载共享库并调用本地方法 最后,我们需要在Java中加载共享库并调用本地方法。例如: ``` static { System.loadLibrary("native-lib"); } NativeTest nativeTest = new NativeTest(); String result = nativeTest.getString(); System.out.println(result); ``` 在此示例中,我们使用System.loadLibrary方法加载共享库“native-lib”,并创建一个NativeTest对象。我们然后调用getString方法,并打印结果。 这就是一个简单JNI示例!

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值