android NDK --java 与 C 语言之间传递数据

使用JNI实现Java与C之间传递数据 2016-02-16 19:58 by 指针空间,5120阅读,0评论,收藏,编辑 Android中使用JNI七个步骤: 1.创建一个android工程 2.JAVA代码中写声明native 方法 public native String helloFromJNI(); 3.用javah工具生成头文件 4. 创建jni目录,引入头文件,根据头文件实现c代码 ... 阅读详情

在java 端定义native 方法,在方法中引入对应的参数,在C代码中接收到java端传递过来的数据,并对数据做响应的处理,最后返回给java端。

创建工程,并在工程下创建一个用于存放本地方法的DataProvider.java

DataProvider.java 的方法如下:

public class DataProvider {
//在C代码中,将java端传递过来的两个值相加然后返回数据给java端
 public native int add(int x,int y);
 //将java中的一个字符串传递给c代码,在c代码中,将字符串后面的加上hello 后返回给java端
 public native String sayHelloInC(String s);
 //将java端的int[] 传递给C代码,C中将每个元素+10,返回给java端
 public native int[] intMethod(int[] iNum);
}

使用javah工具,编译出对应的.h头文件。

在工程的目录的jni目录下的.c文件中,实现对应的native 方法

#include<stdio.h>
#include<stdlib.h>
#include <jni.h>
#include<android/log.h>
#include "com_example_ndkpassdata_DataProvider.h"
#include<malloc.h>
#define LOG_TAG "System.out"
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG,LOG_TAG,__VA_ARGS__)
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO,LOG_TAG, __VA_ARGS__)

//工具方法:将Java中的string 转换成C语言中的char数组
//返回值是char 数组的首地址
//参数二是 java中的String 类型数据

char* Jstring2CStr(JNIEnv* env,jstring jstr){
    //存放char 类型数组的一块内存空间
    char* rtn=NULL;
    //获取到java中的String类
    jclass clsstring=(*env)->FindClass(env,"java/lang/String");
    //创建出String类,该String中存储的数据是"GB2312"
    jstring strencode=(*env)->NewStringUTF(env,"GB2312");
    //获取到clsstring 类中的getBytes方法
    //最后一个参数为对应的签名,表明返回值是byte数组,参数为String 类型(引用类型)
    jmethodID mid=(*env)->GetMethodID(env,clsstring,"getBytes","(Ljava/lang/String;)[B");
    //String.getByte("GB2312")
    //执行mid所指向的方法,将传递进来的str以GB2312的编码方式转成ByteArray数组中的字节,相当于执行 java中String的getByte方法
    jbyteArray barr=(jbyteArray)(*env)->CallObjectMethod(env,jstr,mid,strencode);
    //获取barr的数组长度
    jsize alen=(*env)->GetArrayLength(env,barr);
    //获取到barr中的元素
    jbyte* ba=(*env)->GetByteArrayElements(env,barr,JNI_FALSE);
    if(alen >0){
        //为char数组申请一块内存空间,多申请一个存放 '\0'
        rtn=(char*)malloc(alen+1);
        //由rtn所指向的区域复制alen个直接到ba所指向的区域
        memcpy(rtn,ba,alen);
        rtn[alen]=0;
    }
    //释放掉ba所指向的内存中的全部数据,0表示释放ba所指的全部内存空间
    (*env)->ReleaseByteArrayElements(env,barr,ba,0);//释放空间
    return rtn;

}

JNIEXPORT jint JNICALL Java_com_example_ndkpassdata_DataProvider_add
  (JNIEnv *env, jobject obj, jint x, jint y){
    LOGI("X=%d",x);
    LOGI("Y=%d",y);
    return x+y;
}

JNIEXPORT jstring JNICALL Java_com_example_ndkpassdata_DataProvider_sayHelloInC
  (JNIEnv *env, jobject obj, jstring jstr){
   char* p=Jstring2CStr(env,jstr);
     //在C语言中打印JAVA 端传递过来的字符
   LOGI("in c code=%s",p);
   char* newstr="hello";
   return (*env)->NewStringUTF(env,strcat(p,newstr));
}

JNIEXPORT jintArray JNICALL Java_com_example_ndkpassdata_DataProvider_intMethod
  (JNIEnv *env, jobject obj, jintArray jintarr){
    //GetArraylength 方法获取到传递过来的数组的长度
      int len=(*env)->GetArrayLength(env,jintarr);
       LOGI("len=%d",len);

       //打印出数组在内存中的地址
       //LOGI("dizhi=%#x",&jintarr);
       //将数组所有的元素存入以jint* 为首地址的数组中

       //
       //参数三:获取方式,0代表不以复制的形式获取
       jint* arr=(*env)->GetIntArrayElements(env,jintarr,0);
       //遍历数组中的元素
       int i=0;
       int temp;
       for(;i<len;i++){
           LOGI("arr[%d]=%d",i,*(arr+i));
           //*(arr+i)+=10;
           temp=*(arr+i)+10;
           //使用JNI的规范设置数组中元素的值
           /*
            * 参数二: java端传递过来的数组中的元素
            * 参数三:释放的数组的首地址
            * 参数四:更改要更改的元素后面的几个值(从更改的元素算起,起始值为1)
            * 参数五:更改的元素在内存中的地址值
            *
            */
           (*env)->SetIntArrayRegion(env,jintarr,i,1,&temp);
       }

       //释放内存空间
       /*
        * 参数二:释放哪个元素
        * 参数三:释放的数组的首地址
        * 参数四:0表示释放arr所指向的所有内存
        */
       (*env)->ReleaseIntArrayElements(env,jintarr,arr,0);

       return jintarr;
}

修改jin 目录下的Android.mk文件

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE    := NdkPassData
LOCAL_SRC_FILES := NdkPassData.c
LOCAL_LDLIBS += -llog //因为要使用Logcat 

include $(BUILD_SHARED_LIBRARY)

C代码编写完毕,编译生成对应的.so库

接下来。在java代码中load 进动态库文件,调用本地方法
MainActity.java中的业务代码如下:

package com.example.ndkpassdata;

import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;

public class MainActivity extends Activity {
    static{
        System.loadLibrary("NdkPassData");
    }

    private Button bt1,bt2,bt3;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        bt1=(Button)findViewById(R.id.bt1);
        bt1.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View view) {
                passInt(view);      
            }
        });

        bt2=(Button)findViewById(R.id.bt2);
        bt2.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View view) {

                passString(view);
            }
        });

        bt3=(Button)findViewById(R.id.bt3);
        bt3.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View view) {

                passIntArr(view);
            }
        });


    }

    //返回两数之和
    public void passInt(View view){
        DataProvider provider=new DataProvider();
        int result=provider.add(2, 4);
        Toast.makeText(this, "相加的结果是"+result,Toast.LENGTH_LONG).show();

    }

    //返回修改后的字符串
    public void passString(View view){
        DataProvider provider=new DataProvider();
        String result=provider.sayHelloInC("zhangsan");
        Toast.makeText(this, result,1).show();
    }

    //返回修改后的int 数组
    public void passIntArr(View view){
        int[] arr={1,2,3,4,5};
        System.out.println(arr.toString());
        DataProvider provider=new DataProvider();
        provider.intMethod(arr);
        for(int i=0;i<arr.length;i++){
            System.out.println("java arr["+i+"]="+arr[i]);
        }
    }
}
NDK之Android NDK Android NDK(Native Development Kit)是Android的一个原生开发工具集,它允许开发者使用C和C++等编程语言来编写Android应用程序或游戏的部分代码。 阅读详情

相关推荐

androidjni编程,java和c层的互相通信传递数据

android开发之jni开发,java层native层之间的相互调用,方便广大学者工作者学习参考

【Android -- JNI 和 NDK】Java 和 C/C++ 之间传递参数和返回值

本文主要介绍 JNI 的数据传递上,即 Java 如何传递对象给 C++; 而 C++ 又如何将数据封装成 Java 所需的对象。

Kevin Learn Android 2250

NDKC调用Java函数传参或获取变量

NDK开发时,C/C++调用Java的函数的一些案例; 传递int类型参数: https://blog.youkuaiyun.com/niuba123456/article/details/80978500 传递String类型参数: https://blog.youkuaiyun.com/niuba123456/article/details/80978916 传递多个参数: https://blog.youkuaiyun.com/niuba123456/article/details/80979082 调用静态函数: https://blog.youkuaiyun.com/niuba123456/article/details/80979019 C/C++获取Java的全局变量: 获取int类型和String类型变量并重新赋值: https://blog.youkuaiyun.com/niuba123456/article/details/80990063 获取静态变量: https://blog.youkuaiyun.com/niuba123456/article/details/80990237

java、native数据共享

场景: 为了提高数据处理性能,应用启动把数据库数据加载内存中,在java层使用HashMap维护内存数据,java逐条传输数据给native处理;当增删改查时,内存和数据库同时更新 问题: 由于jni的缘故,高频度调用jni处理数据,每条数据量不大,jni反而成为效率的瓶颈,效率太低 改进方向: 每次处理数据,native可以直接获取所有处理数据,不需要java逐条传输;不影响数据同步(增删改查)...

卓越之路 704

保姆级教程:用ComfyUI+LTX-Video插件,5分钟搞定你的第一个AI视频(RTX 4060实测)

本文提供了一份详细的ComfyUI与LTX-Video插件使用指南,帮助用户在RTX 4060显卡上快速生成AI视频。从环境部署到图形化操作,再到提示词优化和性能调优,全面覆盖AI视频生成的各个环节,让零基础用户也能轻松上手。

weixin_33743661的博客 136

从标准到实战:详解IEC 61000-4-2下的ESD电路防护设计

本文深入解析IEC 61000-4-2标准下的ESD电路防护设计,从静电防护的基础原理到实战应用。详细介绍了接触放电与空气放电的区别、防护器件选型要点(如TVS管和压敏电阻)以及PCB布局的黄金法则,帮助工程师有效提升电子产品的抗静电能力,确保设备在严苛环境下的稳定运行。

weixin_33704234的博客 512

android jni java c_Android使用JNI实现Java与C之间传递数据-Fun言

介绍Java如何将数据传递给C和C回调Java的方法。 java传递数据给C,在C代码中进行处理数据,处理完数据后返回给java。C的回调是Java传递数据给C,C需要用到Java中的某个方法,就需要调用java的方法。Android中使用JNI七个步骤:1.创建一个android工程2.JAVA代码中写声明native 方法 public native String helloFromJNI(...

weixin_32408723的博客 222

基于STM32的频率计(采用外部中断的方式)

前言 最近在了解电赛相关的东西,和指导老师交流一下,我决定先从最简单的频率计做起。 频率计是来检测信号的频率的,在做频率计的时候可以用信号发生器发出的信号来进行测试。 原理 这是最基础的方波,我们可以通过检测上升沿的方式来测量其频率。从周期的角度出发连续两个上升沿的时间就是这个方波的周期,那这个周期分之一就是这个方波的频率了。 在思考了一段时间~~(我是萌新。。)~~ 我觉得有两个方法可以实现,第一个是采用stm32定时器的输入捕获功能,第二个就是用外部中断来实现这个功能。正如标题,我这次采用外部中断的方

qq_45784922的博客 6171

Android NDK中C和java之间数组的传送

最近在android上开发一个PDF阅读器,需要将NDK的数据传送到java中显示。值得注意的是,NDK中用c的内存分配函数分配的内存空间,不能直接return给java中使用。         反正坚持一个原则:C分配的内存只能C来使用,java分配的内存只可以java使用。至于C和java之间的内存交换,NDK提供了额外的函数。        下面举例说明:一个java中分配int[],然

semillon的专栏 9557

基于Playwright的雪球网股票情绪数据自动化采集实战

网络爬虫是自动化获取互联网公开数据的关键技术,其核心原理在于模拟浏览器行为或直接发送HTTP请求以解析网页内容。在金融科技与量化分析领域,实时、稳定的数据源具有极高的技术价值,能够为市场情绪分析、因子挖掘提供基础。面对采用动态加载、复杂反爬机制的现代单页应用,传统的请求库与Selenium方案在稳定性与隐蔽性上面临挑战。本文聚焦于利用Playwright这一现代浏览器自动化工具,通过模拟真实用户交互、监听网络请求,构建一个能够稳定采集雪球社区实时讨论热度的解决方案。该方案不仅解决了动态内容渲染问题,还通过请

weixin_42529328的博客 585

1.triton镜像使用

1)拉取镜像2)启动容器指定模型仓库时可以执行server下的./fetch_model.sh,见2.2部分GPU版本的启动CPU版本的启动区别只在于--gpus=1这个参数注意:docker19.03之前的版本使用gpu要指定显卡硬件名,docker19.03之后的需要安装nvidia-container-toolkit或nvidia-container-runtime安装之后要重启docker查看gpus参数是否安装成功重新执行我遇到了如下错误先使用非GPU版本的。

天启的博客 2077

Android使用JNI实现Java与C之间传递数据

介绍Java如何将数据传递给C和C回调Java的方法。  java传递数据给C,在C代码中进行处理数据,处理完数据后返回给java。C的回调是Java传递数据给C,C需要用到Java中的某个方法,就需要调用java的方法。 Android中使用JNI七个步骤: 1.创建一个android工程 2.JAVA代码中写声明native 方法 public native String helloFr

文忠专栏 4万+

语音测试(二)音频标注(praat)

通过点击红线下方的圆点进行区域划分,在区域中标注所属的类别。按住Alt+Backspace 键取消蓝色线条。

beishida123的博客 3734

Java与C之间传递数据

介绍Java如何将数据传递给C和C回调Java的方法。  java传递数据给C,在C代码中进行处理数据,处理完数据后返回给java。C的回调是Java传递数据给C,C需要用到Java中的某个方法,就需要调用java的方法。 Android中使用JNI七个步骤: 1.创建一个a

hgl868的专栏 4705

基于matlab的CNN验证码识别系统(UI界面版)

基于matlab的CNN验证码识别系统(UI界面版),CNN验证码识别系统包括数据集处理、模型搭建、模型训练、界面设计与实现

在职AI算法工程师,擅长计算机视觉,YOLO目标检测、分割等,擅长web、pyqt界面可视化,好内容持续更新中,来这里跟大家一起学习,共同进步 483

科技与伦理的平衡点:人类计算的伦理

科技与伦理的平衡点:人类计算的伦理 关键词 科技与伦理 人类计算 隐私问题 道德决策自动化 公平性与偏见 法律与社会责任 摘要 本

AI天才研究院 1162

Android NDK 开发(四)java传递数据到C【转】

转载请注明出处:http://blog.youkuaiyun.com/allen315410/article/details/41845701 前面几篇文章介绍了AndroidNDK开发的简单概念、常见错误及处理和从第一个Hello World开始实际做一个简单的JNI开发示例,相信看完之后,大家对NDK开发有了一个概念上的认识了,那么接下来我们需要再深入一下NDK的开发,我们知道ND...

zzb2760715357的博客 148

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

Android NDK开发(四)——Java传递数据到C

前面几篇文章介绍了Android NDK开发的简单概念、常见错误及处理和从第一个Hello World开始实际做一个简单的JNI开发示例,相信看完之后,大家对NDK开发有了一个概念上的认识了,那么接下来我们需要再深入一下NDK的开发,我们知道NDK开发就是使用JNI这层“协议”在Java和C之间起个“桥梁”的作用,将Java和Native C之间联立起来,让Java和C直接的数据进行互调。谈到Java和C之间的数据调用,那么Java是怎样传递数据到C中的呢,C拿到数据处理完后又怎样将处理后的数据回传给Jav

Vincent的专栏 5069

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

java 传递脚本给c_Android NDK 开发(四)java传递数据到C【转】

前面几篇文章介绍了AndroidNDK开发的简单概念、常见错误及处理和从第一个Hello World开始实际做一个简单的JNI开发示例,相信看完之后,大家对NDK开发有了一个概念上的认识了,那么接下来我们需要再深入一下NDK的开发,我们知道NDK开发就是使用JNI这层“协议”在Java和C之间起个“桥梁”的作用,将Java和Native C之间联立起来,让Java和C直接的数据进行互调。谈到Ja...

weixin_30444625的博客 223

廖雪峰Python教程[完整版]

廖雪峰的python教程整理的,已经排好版了,而且还是完整的,适合小白

Android 使用JNI实现Java与C之间传递数据

http://www.cppblog.com/xkjy3000/archive/2013/11/24/204416.aspx

piaofenglanyan的专栏 531

ndk开发中利用java与c之间互相传递数据

1、DataProvider package com.njupt.ndk_passdata; public class DataProvider { public native int add(int x,int y); public static native int sub(int x,int y); public native String sayHelloInC(Strin

黄俊东的专栏 1930

jni c 传递对象到java_Android使用JNI实现Java与C之间传递数据(转)

介绍Java如何将数据传递给C和C回调Java的方法。 java传递数据给C,在C代码中进行处理数据,处理完数据后返回给java。C的回调是Java传递数据给C,C需要用到Java中的某个方法,就需要调用java的方法。Android中使用JNI七个步骤:1.创建一个android工程2.JAVA代码中写声明native 方法 public native String helloFromJNI(...

weixin_36299472的博客 626

java jint_Android使用JNI实现Java与C之间传递数据

介绍Java如何将数据传递给C和C回调Java的方法。 java传递数据给C,在C代码中进行处理数据,处理完数据后返回给java。C的回调是Java传递数据给C,C需要用到Java中的某个方法,就需要调用java的方法。Android中使用JNI七个步骤:1.创建一个android工程2.JAVA代码中写声明native 方法 public native String helloFromJNI(...

weixin_33464176的博客 463
上一篇: android NDK java-c中的签名
下一篇: android NDK--C 调用java
技术搬运工
博客等级 码龄11年 3粉丝 9原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值