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

JNI程序如何进行参数传递 JNI程序如何进行参数传递。 阅读详情
介绍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();

3.用javah工具生成头文件

4. 创建jni目录,引入头文件,根据头文件实现c代码

5.编写Android.mk文件

6.Ndk编译生成动态库

7.Java代码load 动态库.调用native代码

Java调用C进行数据传递

 这里分别传递整形、字符串、数组在C中进行处理。

声明native 方法:

[java]  view plain copy
  1. public class DataProvider {  
  2.     // 两个java中的int 传递c 语言 ,  c语言处理这个相加的逻辑,把相加的结果返回给java  
  3.     public native int add(int x ,int y);  
  4.       
  5.     //把一个java中的字符串传递给c语言, c 语言处理下字符串, 处理完毕返回给java   
  6.     public native String sayHelloInC(String s);  
  7.   
  8.     //把一个java中int类型的数组传递给c语言, c语言里面把数组的每一个元素的值 都增加5,   
  9.     //然后在把处理完毕的数组,返回给java  
  10.     public native int[] intMethod(int[] iNum);   
  11. }  


以上方法要在C中实现的头文件,头文件可以理解为要在C中实现的方法

其中 JENEnv* 代表的是java环境 , 通过这个环境可以调用java的方法,jobject 表示哪个对象调用了 这个c语言的方法, thiz就表示的是当前的对象

[cpp]  view plain copy
  1. /* DO NOT EDIT THIS FILE - it is machine generated */  
  2. #include <jni.h>  
  3. /* Header for class cn_itcast_ndk3_DataProvider */  
  4.   
  5. #ifndef _Included_cn_itcast_ndk3_DataProvider  
  6. #define _Included_cn_itcast_ndk3_DataProvider  
  7. #ifdef __cplusplus  
  8. extern "C" {  
  9. #endif  
  10. /* 
  11.  * Class:     cn_itcast_ndk3_DataProvider 
  12.  * Method:    add 
  13.  * Signature: (II)I 
  14.  */  
  15. JNIEXPORT jint JNICALL Java_cn_itcast_ndk3_DataProvider_add  
  16.   (JNIEnv *, jobject, jint, jint);  
  17.   
  18. /* 
  19.  * Class:     cn_itcast_ndk3_DataProvider 
  20.  * Method:    sayHelloInC 
  21.  * Signature: (Ljava/lang/String;)Ljava/lang/String; 
  22.  */  
  23. JNIEXPORT jstring JNICALL Java_cn_itcast_ndk3_DataProvider_sayHelloInC  
  24.   (JNIEnv *, jobject, jstring);  
  25.   
  26. /* 
  27.  * Class:     cn_itcast_ndk3_DataProvider 
  28.  * Method:    intMethod 
  29.  * Signature: ([I)[I 
  30.  */  
  31. JNIEXPORT jintArray JNICALL Java_cn_itcast_ndk3_DataProvider_intMethod  
  32.   (JNIEnv *, jobject, jintArray);  
  33.   
  34. #ifdef __cplusplus  
  35. }  
  36. #endif  
  37. #endif  


C代码出了要引用头文件外,还要引入日志信息,以方便在C 中进行调试

[cpp]  view plain copy
  1. //引入头文件  
  2. #include "cn_itcast_ndk3_DataProvider.h"  
  3. #include <string.h>  
  4. //导入日志头文件  
  5. #include <android/log.h>  
  6. //修改日志tag中的值  
  7. #define LOG_TAG "logfromc"  
  8. //日志显示的等级  
  9. #define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)  
  10. #define LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)  
  11.   
  12. // java中的jstring, 转化为c的一个字符数组  
  13. char*   Jstring2CStr(JNIEnv*   env,   jstring   jstr)  
  14. {  
  15.      char*   rtn   =   NULL;  
  16.      jclass   clsstring   =   (*env)->FindClass(env,"java/lang/String");  
  17.      jstring   strencode   =   (*env)->NewStringUTF(env,"GB2312");  
  18.      jmethodID   mid   =   (*env)->GetMethodID(env,clsstring,   "getBytes",   "(Ljava/lang/String;)[B");  
  19.      jbyteArray   barr=   (jbyteArray)(*env)->CallObjectMethod(env,jstr,mid,strencode); // String .getByte("GB2312");  
  20.      jsize   alen   =   (*env)->GetArrayLength(env,barr);  
  21.      jbyte*   ba   =   (*env)->GetByteArrayElements(env,barr,JNI_FALSE);  
  22.      if(alen   >   0)  
  23.      {  
  24.       rtn   =   (char*)malloc(alen+1);         //new   char[alen+1]; "\0"  
  25.       memcpy(rtn,ba,alen);  
  26.       rtn[alen]=0;  
  27.      }  
  28.      (*env)->ReleaseByteArrayElements(env,barr,ba,0);  //释放内存  
  29.   
  30.      return rtn;  
  31. }  
  32.   
  33. //处理整形相加  
  34. JNIEXPORT jint JNICALL Java_cn_itcast_ndk3_DataProvider_add  
  35.   (JNIEnv * env, jobject obj, jint x, jint y){  
  36.     //打印 java 传递过来的 jstring ;  
  37.     LOGI("log from c code ");  
  38.     LOGI("x= %ld",x);  
  39.     LOGD("y= %ld",y);  
  40.     return x+y;  
  41. }  
  42.   
  43. //处理字符串追加  
  44. JNIEXPORT jstring JNICALL Java_cn_itcast_ndk3_DataProvider_sayHelloInC  
  45.   (JNIEnv * env, jobject obj, jstring str){  
  46.   
  47.     char* p =  Jstring2CStr(env,str);  
  48.     LOGI("%s",p);  
  49.     char* newstr = "append string";  
  50.   
  51.     //strcat(dest, sorce) 把sorce字符串添加到dest字符串的后面  
  52.     LOGI("END");  
  53.     return (*env)->NewStringUTF(env, strcat(p,newstr));  
  54. }  
  55.   
  56. //处理数组中的每一个元素  
  57. JNIEXPORT jintArray JNICALL Java_cn_itcast_ndk3_DataProvider_intMethod  
  58.   (JNIEnv * env, jobject obj, jintArray arr){  
  59.     // 1.获取到 arr的大小  
  60.   
  61.     int len = (*env)->GetArrayLength(env, arr);  
  62.     LOGI("len=%d", len);  
  63.   
  64.     if(len==0){  
  65.         return arr;  
  66.     }  
  67.     //取出数组中第一个元素的内存地址  
  68.     jint* p = (*env)-> GetIntArrayElements(env,arr,0);  
  69.     int i=0;  
  70.     for(;i<len;i++){  
  71.         LOGI("len=%ld", *(p+i));//取出的每个元素  
  72.         *(p+i) += 5; //取出的每个元素加五  
  73.     }  
  74.     return arr;  
  75. }  

编写Android.mk文件

[cpp]  view plain copy
  1. LOCAL_PATH := $(call my-dir)  
  2.   
  3. include $(CLEAR_VARS)  
  4.   
  5. LOCAL_MODULE    := Hello  
  6. LOCAL_SRC_FILES := Hello.c   
  7. #增加 log 函数对应的log 库  liblog.so  libthread_db.a  
  8. LOCAL_LDLIBS += -llog  
  9.   
  10. include $(BUILD_SHARED_LIBRARY)  

 Java代码load 动态库.调用native代码

[java]  view plain copy
  1. static{  
  2.         System.loadLibrary("Hello");  
  3.     }  
  4.     DataProvider dp;  
  5.       
  6.     @Override  
  7.     public void onCreate(Bundle savedInstanceState) {  
  8.         super.onCreate(savedInstanceState);  
  9.         setContentView(R.layout.main);  
  10.         dp = new DataProvider();  
  11.     }  
  12.       
  13.     //add对应的事件  
  14.     public void add(View view){  
  15.         //执行C语言处理数据  
  16.         int result = dp.add(3, 5);  
  17.         Toast.makeText(this, "相加的结果"+ result, 1).show();      
  18.     }  

 

C中回调java方法

声明native 方法:

[java]  view plain copy
  1. public class DataProvider{  
  2.     public native void callCcode();  
  3.     public native void callCcode1();  
  4.     public native void callCcode2();  
  5.       
  6.     ///C调用java中的空方法    
  7.     public void helloFromJava(){  
  8.         System.out.println("hello from java ");  
  9.     }  
  10.     //C调用java中的带两个int参数的方法  
  11.     public int Add(int x,int y){  
  12.         System.out.println("相加的结果为"+ (x+y));  
  13.         return x+y;  
  14.     }  
  15.     //C调用java中参数为string的方法  
  16.     public void printString(String s){  
  17.         System.out.println("in java code "+ s);  
  18.     }  
  19. }  

头文件可以用jdk自带的javah进行自动生成,使用javap -s可以获取到方法的签名。

C代码实现回调需要三个步骤:首先要要获取到 某个对象 , 然后获取对象里面的方法  ,最后 调用这个方法  .

[cpp]  view plain copy
  1. #include "cn_itcast_ndk4_DataProvider.h"  
  2. #include <string.h>  
  3. #include <android/log.h>  
  4. #define LOG_TAG "logfromc"  
  5. #define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)  
  6. #define LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)  
  7.   
  8. //1.调用java中的无参helloFromJava方法  
  9. JNIEXPORT void JNICALL Java_cn_itcast_ndk4_DataProvider_callCcode  
  10.   (JNIEnv * env , jobject obj){  
  11.     // 获取到DataProvider对象  
  12.     char* classname = "cn/itcast/ndk4/DataProvider";  
  13.     jclass dpclazz = (*env)->FindClass(env,classname);  
  14.     if (dpclazz == 0) {  
  15.             LOGI("not find class!");  
  16.         } else  
  17.             LOGI("find class");  
  18.     //第三个参数 和第四个参数 是方法的签名,第三个参数是方法名  , 第四个参数是根据返回值和参数生成的  
  19.     //获取到DataProvider要调用的方法  
  20.     jmethodID methodID = (*env)->GetMethodID(env,dpclazz,"helloFromJava","()V");  
  21.     if (methodID == 0) {  
  22.             LOGI("not find method!");  
  23.         } else  
  24.             LOGI("find method");  
  25.     //调用这个方法  
  26.     (*env)->CallVoidMethod(env, obj,methodID);  
  27. }  
  28.   
  29. // 2.调用java中的printString方法传递一个字符串  
  30. JNIEXPORT void JNICALL Java_cn_itcast_ndk4_DataProvider_callCcode1  
  31.   (JNIEnv * env, jobject obj){  
  32.     LOGI("in code");  
  33.     // 获取到DataProvider对象  
  34.     char* classname = "cn/itcast/ndk4/DataProvider";  
  35.     jclass dpclazz = (*env)->FindClass(env,classname);  
  36.     if (dpclazz == 0) {  
  37.             LOGI("not find class!");  
  38.         } else  
  39.             LOGI("find class");  
  40.     // 获取到要调用的method  
  41.     jmethodID methodID = (*env)->GetMethodID(env,dpclazz,"printString","(Ljava/lang/String;)V");  
  42.     if (methodID == 0) {  
  43.             LOGI("not find method!");  
  44.         } else  
  45.             LOGI("find method");  
  46.   
  47.     //调用这个方法  
  48.     (*env)->CallVoidMethod(env, obj,methodID,(*env)->NewStringUTF(env,"haha"));  
  49. }  
  50.   
  51. // 3. 调用java中的add方法 , 传递两个参数 jint x,y  
  52. JNIEXPORT void JNICALL Java_cn_itcast_ndk4_DataProvider_callCcode2  
  53.   (JNIEnv * env, jobject obj){  
  54.     char* classname = "cn/itcast/ndk4/DataProvider";  
  55.     jclass dpclazz = (*env)->FindClass(env,classname);  
  56.     jmethodID methodID = (*env)->GetMethodID(env,dpclazz,"Add","(II)I");  
  57.     (*env)->CallIntMethod(env, obj,methodID,3l,4l);  
  58. }  
ST7789T3与CST816D驱动全解析,面试技巧第11篇:嵌入式面试场景问答 10 连发。 SPI模式下,SCLK、MOSI、CS、DC、RST为必需引脚;8080模式下需连接D0-D7、WR、RD等信号线。CST816D触摸芯片通常通过I2C接口通信,需连接SCL、SDA及INT(中断)引脚。确保电源引脚(VCC、GND)稳定供电,ST7789T3典型工作电压为3.3V。显示异常时检查时序参数,如SPI时钟频率(建议≤40MHz)、数据建立时间。初始化流程需发送一系列命令序列,包括设置像素格式、扫描方向、帧率控制等。扫描方向(MADCTL)可调整显示旋转角度,需根据实际硬件布局配置。 阅读详情

相关推荐

具身智能落地实战:制造业、物流与电力的工业级方案设计

具身智能是一种融合感知、推理与物理执行的智能范式,其核心在于构建具备因果建模能力、多模态闭环反馈和实时动作规划的行动主体。区别于通用AI或传统自动化,它依托多模态大模型、高精度力觉/触觉传感及Sim2Real仿真技术,实现对真实物理环境的深度理解与自适应交互。技术价值体现在可解释性决策、毫秒级跨模态协同与零停机容错能力,已规模化应用于制造业质检、物流破损鉴定、电力绝缘子巡检等强约束工业场景。本文聚焦‘行业应用方案解决方案’这一高频搜索需求,系统拆解从工位筛选、分层架构设计到72小时现场交付的全链路工程方法论

weixin_30952479的博客 300

android JNI 传参

本篇将介绍在JNI编程中如何传递参数和返回值。 首先要强调的是,native方法不但可以传递Java 的基本类型做参数,还可以传递更复杂的类型,比如String,数组,甚 至自定义的类。这一切都可以在jni.h中找到答案。 1. Java基本类型的传递 用过Java的人都知道,Java中的基本类型包括boolean,byte ,char,short,int,long,float,double

ACanoe的专栏 3795

window下移动设备/硬盘报错位置不可用

移动硬盘指示灯亮,但电脑上不显示 报错信息 : 无法访问E:\。参数错误。 报错原因: 移动硬盘打不开提示参数错误,是因为这个H盘的文件系统内部结构损坏导致的。要怎么恢复里面的数据呢? https://jingyan.baidu.com/article/cb5d6105a80242005c2fe0c3.html 解决办法 : 不用格式化修复方法 方法一: 1、单击–开始–运行–输入cmd; 2、...

qq_40907977的博客 4928

jni java c 变量对应_Jni中C++和Java的参数传递 参数对照

如何使用JNI的一些基本方法和过程在网上多如牛毛,如果你对Jni不甚了解,不知道Jni是做什么的,如何建立一个基本的jni程序,或许可以参考下面下面这些文章:利用VC++6.0实现JNI的最简单的例子这些资料的例子中,大多数只是输入一些简单的参数,获取没有参数。而在实际的使用过程中,往往需要对参数进行处理转换。才可以被C/C++程序识别。比如我们在C++中有一个结构(Struct)DiskInfo...

weixin_39634022的博客 492

【学习路线】 游戏客户端开发入门到进阶

游戏开发是一个交叉性极强的技术领域,对开发者提出了高维度的要求。作为初学者,不要急于求成,打牢基础、注重原理、勤于实践,你的成长将会非常快速而稳健。希望这份学习路线与书单能为你指明方向,迈出职业开发者的第一步。

hhw_hhw的博客 2128

3D Slicer肺部CT病灶体积测量:阈值法实操全流程

在医学影像分析中,病灶体积的精准测量是肿瘤评估、疗效随访和科研统计的重要基础。传统逐层手动勾画不仅耗时,且主观差异大,而基于CT值的阈值分割技术,通过设定灰度区间自动提取目标体素,能够快速生成三维分割结果,具有高效、可重复、边界标准统一的优势,尤其适用于肺部实性结节这类与周围肺实质对比度高的病灶。理解体素与CT值的关系,掌握阈值范围的设定逻辑,并配合连通域分析、边缘修正等工程化操作,即可在3D Slicer中稳定获得可靠的体积数据。本文从技术原理出发,系统梳理了DICOM导入、窗宽窗位调节、阈值选择、三维重

weixin_29050271的博客 251

JNI 传递和返回基本参数

Java 中的基本类型包括 boolean,byte,char,short,int,long,float,double 这样几种,本文主要介绍上层向底层传递基本类型数据,以及底层向上层返回基本数据类型的情况。jni静态注册,jni动态注册,jni返回double型数据, jni返回float型数据,jni返回long型数据,jni返回java对象,jni返回传递对象

AlanWang4523 1万+

无人驾驶感知融合——横摆角速度的多源估计算法解析

本文深入解析了无人驾驶感知融合中的横摆角速度多源估计算法,详细介绍了轮速差法、侧向加速度法、曲率法和惯性传感器直读法四种计算方法及其优缺点。通过卡尔曼滤波实战案例,展示了多源融合算法在提升精度和稳定性方面的显著优势,并探讨了工程实践中的时间对齐、坐标系统一等关键问题。

weixin_31458015的博客 462

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

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

piaofenglanyan的专栏 531

Claude Code 里的 MCP 连接失败到底在报什么

文档还说明,HTTP 类型、stdio 类型等 MCP server 的接入方式不同,stdio server 会被 Claude Code 当作本地进程拉起,而 HTTP server 则需要 Claude Code 去访问一个已经存在的 HTTP endpoint。把这段输出翻成更接地气的运维语言,就是 Claude Code 已经知道我们想接两个外部能力,一个是 SAP ADT 官方 MCP,一个是 Chrome DevTools MCP,但当前没有一个完成握手。,因为它的信号更明确。

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 145

从 SAP Gateway 旧 add-ons 卸载到 SAP S/4HANA 转换的清理路线

摘要: SAP Gateway系统的维护难点往往源于历史遗留组件的堆积,而非OData服务本身的复杂性。早期系统为支持多种服务类型而安装的各类add-ons(如IW_SCS、IW_CNT、GW_CORE等),随着系统升级和团队更替逐渐成为技术负债。自SAP NetWeaver 7.40起,核心功能已整合至SAP_GWFND组件,使架构显著简化。在向S/4HANA迁移时,需重点清理已废弃的add-ons(如IW_SCS、IW_GIL等),但必须谨慎验证其关联服务是否仍被调用。组件清理需结合系统日志和调用链分析

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 423

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 nativeString helloFromJNI()...

weixin_33700405的博客 321

基于HTML5的酒店在线预订系统设计与实现

1.背景介绍 酒店预订系统,作为现代酒店业务中的重要一环,其便捷性、智能化程度直接影响着酒店的服务质量和经营效果。近年来,随着互联网技术和移动设备的快速发展,以及消费者行为的日益电子化,酒店预订系统也正在经历一场深刻的变革。传统的酒店预订系统往往依赖于复杂的软件安装和硬件设备,而新一代的酒店预订系统则更加强调在线、移动和云端的特性。HTML5作为一种前

AI天才研究院 1909

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

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

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

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

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

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...

上一篇: Android中JNI的使用方法
下一篇: Android使用UncaughtExceptionHandler捕获全局异常
stonenotes123
博客等级 码龄15年 30粉丝 176原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值