JNI简单示例

JNI编程示例 源代码地址: 链接:百度网盘 请输入提取码 提取码:gtlz 一、Demo介绍 为了更深入的理解Jni编程知识,我们通过一个简单demo把相关知识用实际代码串起来,会有更清晰的认识。在这个demo中,涉及数组处理、字符串处理、类成员变量访问修改等内容,基本涵盖了常见的用法。 相关介绍 涉及文件 (java代码/xml布局文件) demo界面示例 主界面 点击button进入对应示例 s 阅读详情
 

JNI简单示例

例子简介:

    这个简单的例子展示了上层应用程序如果利用JNI接口和底层驱动进行交互:上层应用通过两个按钮控制灯的开关。

步骤:

一、应用程序

    包含两个按钮,一个是开,一个是关,另外包含一个RadioButton指示灯的状态。

 

    关键代码:

package com.android.test;

 

public class LightControl extends Activity {

    @Override

    public void onCreate(Bundle savedInstanceState) {

        System.loadLibrary("light_control");//加载liblight_control.so动态库

        init_native();

    }

 

    //声明JNI方法

    private static native void light_control(int onoff);

    private static native int init_native();

    private static native int destroy_native();

}

二、JNI接口

    JNI层需要打开设备,并提供上层应用程序的读写接口,并在退出时释放占有的相关资源。由于HAL层是用C/C++语言编写的,而上层应用程序是由java语言编写的,因此中间层与上层程序之间沟通的桥梁,就是众所周知的JNI接口(JNI接口不是唯一的桥梁,采用socket等同样可以做到)。

 

    JNI需要完成如下工作:建立一个C/C++函数与Java函数映射的表,即JNINativeMethod表,对应上层应用中声明的JNI方法。

static JNINativeMethod method_table[] = {

    {"light_control","(I)V",(void*)light_control_native},

    { "init_native", "()I", (void*)init_native },

    { "destroy_native", "()I", (void*)destroy_native },

};

    为了理解上面表的含义,先来看看JNINativeMethod结构体的定义:

typedef struct {

    const char* name;

    const char* signature;

    void*       fnPtr;

} JNINativeMethod;

    name为指向java代码中函数的名称,fnPtr为本地函数指针,signature为描述函数参数和返回值类型的字符串,其中函数参数为java代码中的函数参数,本地函数的参数会多两个:JNIEnv *env和jobject clazz。

    从上面的method_table[]映射表可以看出,一共有三组函数映射,java代码中的light_control函数映射到本地函数light_control_native上,init_native函数映射到本地函数init_native上,destroy_native函数映射到本地函数destroy_native函数上。每个映射中的第二字符串,是函数参数和返回值类型的描述字符串,比如"(I)V",括号里面的每一个字符(或一组以L开头分号结束的字符串)都对应描述了函数的一个参数,紧跟在括号后面的字符(串)描述了函数的返回值类型。

    因此需要在本地代码中完成下面三个函数的定义:

    static void light_control_native(JNIEnv *env, jobject clazz, jint onoff)

    static jint init_native(JNIEnv *env, jobject clazz)

    static jint destroy_native(JNIEnv *env, jobject clazz)

    然后定义一个名为JNI_OnLoad的函数,注意该函数名必须为JNI_OnLoad,且需要用extern “C”声明为C语言方式编译和链接的函数(在源文件为c++文件时才需要),同时返回值类型必须为jint。

extern "C" jint JNI_OnLoad(JavaVM* vm, void* reserved)

{

    ......//此处省略

    return JNI_VERSION_1_4;

}

    这些代码将被编译为动态库,比如例子中编译成了liblight_control.so动态库。那么上层程序可以通过System.loadLibrary("light_control")来加载该动态库。注意参数字符串是去掉”lib”和”.so”的库文件名称,同时需要确保liblight_control.so放置于/system/lib目录下。如果放置于其它地方,可以通过System.load(path)来加载,其中path为动态库文件的全路径名称。

    在动态库被加载后,会立即调用该库里面定义的JNI_OnLoad函数。因此需要在该函数中调用jniRegisterNativeMethods()来完成函数映射表在dalvik上的注册:

    jniRegisterNativeMethods(env, "com/android/test/LightControl",method_table, NELEM(method_table))

    env为dalvik的运行环境对象,字符串"com/android/test/LightControl"是java层的JNI接口类的包名和类名。method_table即为上面定义的函数映射表数组。

    在完成函数映射表数组的注册之后,java层程序就可以通过呼叫其JNI接口方法,来调用本地代码的JNI接口函数了。例如上面的例子中,在java层程序中通过调用light_control(onoff),就可以透过JNI接口调用本地代码的light_control_native(env,clazz, onoff)函数了。其中env和clazz参数是在dalvik环境调用本地代码函数时添加的两个参数,后面会分析其作用。

    最后需要写一个Android.mk来将这些代码编译成动态库。主要的编译设定为:

    LOCAL_SRC_FILES:= com_android_test_LightControl.cpp

    定义这次编译的源代码文件。

    LOCAL_SHARED_LIBRARIES := \

    libandroid_runtime \

    libcutils \

    libnativehelper

    定义在连接时相关的库,其中libcutils在用到LOGD等log信息打印函数的时候才需要。

    LOCAL_MODULE:= liblight_control

    定义生成的动态库的文件名为liblight_control.so。

 

三、底层驱动

    在light_init()初始化函数中:

int light_init(void)

{

    int ret;

       printk("init light control\n");

    ret = register_chrdev(LIGHT_CTL_MAJOR_NUM, DEV_NAME, &light_ctl_ops);

       light_ctl_class = class_create(THIS_MODULE, DEV_NAME);

       device_create(light_ctl_class, NULL, MKDEV(LIGHT_CTL_MAJOR_NUM, LIGHT_CTL_MINOR_NUM), NULL, DEV_NAME);

      

    if(ret < 0){

        printk("Fail to register the light control device! ret=%d\n", ret);

        return ret;

    }

    return 0;

}

    注册一个字符设备,其中DEV_NAME为"light_ctl",建立light_ctl_class的目的是为了在加载驱动后,会自动由udev在/dev目录下生成对应的设备文件:/dev/light_ctl。

对驱动的控制通过ioctl来完成:

static int light_status = 0;

int light_ctl_ioctl(struct inode *inode, struct file *file,

                 unsigned int cmd, unsigned long arg)

{

    int value;

      

    switch(cmd)

    {

           case LIGHT_CTL_SET:                    

                     if(copy_from_user(&value,(void *)arg,sizeof(int)))

                            return - EFAULT;

                     else

                            light_status = value;

               break;

              

              case LIGHT_CTL_GET:

                     value = light_status;

                     if(copy_to_user((void *)arg, &value, sizeof(int)))

                     break;

       

           default :

                 printk("Unsupported command!\n");

               break;

    }

 

    return 0;

}

    从ioctl函数中可以看出,在应用程序中,可以设置变量light_status的值,也可以读取其值。这些都是属于linux驱动设计的范畴,详细可以参考《Linux设备驱动程序》这本书。

JNI C Linux平台:一个简单的示例程序 以下是一个在Linux平台上使用JNI(Java Native Interface)和C语言编写的简单示例程序。这个简单的示例演示了如何在Linux平台上使用JNI和C语言进行函数调用和数据传递。您可以根据自己的需求扩展和修改这个示例,以实现更复杂的功能。接下来,我们需要使用Javah工具生成C头文件。然后,我们需要编写一个简单的Makefile来编译C代码并生成共享库。首先,我们需要编写一个Java类来加载C本地库并调用C函数。,我们将在C代码中实现该方法。头文件以获取JNI函数的声明,并包含了生成的。 阅读详情

相关推荐

QGIS-空间分析-核密度分析

本文在QGIS软件中使用核密度估计法分析全球历年的地震数据,旨在分析出地震频发且严重的区域,为地震防控提供参考依据。全球历年地震数据来源于网络,仅用于技术学习探索。通过核密度分析,可以观察到南美、美国西部海岸线和太平洋北部区域在全球地震分布状态中是最为集中和强烈的。

imxiezy的博客 2467

JNI的代码示例

打开刚创建的ideal项目中生成的edu_hut_JNIDemo.h文件,全选里面的内容。找到你本地安装的jdk的include项目目录和jdk的include下面win32目录。在JNI中补充如下代码,System.load()里面写Dll3.dll的路径。把Dll3.h文件下的函数名复制到Dll3.cpp中,并书写处理逻辑。把鼠标移动到edu.hut软件包上面,新建一个终端终端。粘贴到Dll3.h文件中的#endif下方。选择具有导出的DLL的动态链接库的模板。在头文件中打开Dll3.h头文件。

w14727619798的博客 652

无刷电机FOC控制入门:磁场、洛伦兹力与坐标转换详解

本文深入解析无刷电机FOC(磁场定向控制)的核心原理,从电磁学基础的磁场与洛伦兹力出发,详细阐述了如何通过Clarke变换、Park变换等坐标转换技术,将三相交流解耦为直流量进行控制,最终利用SVPWM技术实现平滑、高效的电机驱动。文章旨在帮助开发者理解FOC的物理本质与数学框架,为机器人、无人机等高性能应用奠定基础。

weixin_29306011的博客 267

菠萝菠萝蜜

/ a_u8_ledsts 表示LED点灯状态,0表示熄灭,1表示点亮。// 这里假设LED从1开始编号,实际情况可能需要根据硬件接口进行调整。// 在这里实现获取输入数据的逻辑,假设返回一个固定值用于示例。// 在这里实现LED点灯控制逻辑,假设输出点灯状态到硬件。// 这里只是示例,实际代码需要根据具体硬件接口进行编写。// 根据输入数据进行计算得出LED点灯个数。// 输出点灯驱动接口,用于控制LED灯的点亮状态。// 将LED点灯个数转换为点灯控制。// 输入数据获取接口,用于获取输入数据。

优快云YGN的博客 124

教程:使用树莓派连接Pixhawk飞控

教程:使用树莓派连接Pixhawk飞控树莓派可以与Pixhawk飞控相连,读取飞控中的状态信息,同时对飞控发送指令。树莓派作为一个更高性能的计算平台,可以运行图像识别、机器学习、实时路径规划等程序,为开源无人机带来了无限可能。本文将介绍如何在树莓派上使用APSync。不需要了解Linux,即可将树莓派连接到Pixhawk飞控。使用的器材为: Pixhawk飞控 树莓派3B(Raspberry Pi

Roger今天好好搬砖了吗 5万+

FPGA驱动OV5640:从SCCB协议到图像数据采集的实战解析

本文详细解析了使用FPGA驱动OV5640摄像头模组的完整流程,从SCCB协议通信、寄存器配置到图像数据采集。重点阐述了SCCB(与I2C类似)协议的实现细节、关键的上电复位时序,以及如何通过状态机解析视频流时序并捕获图像数据,为嵌入式视觉开发提供了实战指南。

weixin_29191761的博客 187

Android字符设备驱动及应用层从jni控制GPIO实战

本文主要讲述从实际项目中一个GPIO口控制一个加密芯片上下电的功能,提供动态库给客户,并有Android应用层apk调用.so库文件的例子,希望能为大家入门带来帮助! 以下描述参考摘录了别人的话:http://koliy.iteye.com/blog/1424304 android应用层要访问驱动,一般有三种方法。  1.应用层 ---> framwork层JNI ---> 驱动c  2.

qf0727的专栏 9973

AUTOSAR进阶图解==>AUTOSAR_SWS_DefaultErrorTracer

AUTOSAR Default Error Tracer (DET)是AUTOSAR架构中的核心错误追踪模块,提供统一的错误报告机制。DET能够处理开发错误、运行时错误和瞬态故障三类问题,支持模块级和实例级的配置管理。模块架构上,DET通过Det_API接口与其他模块交互,可配置转发错误至诊断事件管理器(DEM)或调试日志追踪(DLT)。其配置结构包含全局参数和模块实例参数,允许灵活控制错误报告行为。DET在AUTOSAR 4.3.0版本中从DevelopmentErrorTracer扩展而来,增强了错误处

一名留德华的,康德的信徒的,专注于汽车电子领域的博客 909

JNI 简单示例

JNI即Java Native Interface(Java本地接口),是一个协议,主要作用为:实现Java调用c/c++代码(类库),或者C/C++调用Java代码。本文主要介绍通过JNI实现java调用C/C++ 通过Java jni来调用native code,需要如下几个步骤: 编写java代码,使用native关键字声明本地方法接口(例如:native void printstr(S...

赶路人儿 1336

在Ubuntu上安装Node.js编程

在Ubuntu操作系统上安装Node.js是非常简单的,本文将为您提供详细的安装步骤。这是一个简单的Node.js HTTP服务器示例,它将在本地主机的端口3000上监听请求,并返回"Hello, World!npm是Node.js的包管理器,您可以使用它来安装和管理Node.js模块。您已成功在Ubuntu上安装了Node.js,并创建并运行了一个简单的Node.js应用程序。现在,您已经成功安装了Node.js和npm,让我们创建一个简单的Node.js应用程序并运行它。如有任何疑问,请随时提问。

CodeNexus的博客 3524

XDMA流传输模式

XDMA 流传输模式(Streaming DMA)​ 是 Xilinx FPGA 通过 PCIe 与主机进行 ​实时流式数据传输 的核心机制,

浩瀚之水的专栏 3434

一个简单的JNI示例

Java Native Interface(JNI)是Java语言的本地编程接口,是J2SDK的一部分。在java程序中,我们可以通过JNI实现一些用java语言不便实现的功能。通常有以下几种情况我们需要使用JNI来实现。 标准的java类库没有提供你的应用程序所需要的功能,通常这些功能是平台相关的 你希望使用一些已经有的类库或者应用程序,而他们并非用java语言编写的 程序的某些部分对速度

xt_chaoji的专栏 474

PyMuPDF为PDF文件添加注释

我将介绍如何使用PyMuPDF库来为PDF文件添加注释,包括文本注释、高亮注释、下划线注释等15种注释的使用方法。

布啦啦 2242

android JNI 的简单示例

这段时间接触到JNI的东西,网上虽然有很多写的不错的例子,还是写下自己的历程。 我的环境是:XP\android开发环境。 1:下载安装Cygwin. Cygwin is: a collection of tools which provide a Linux look and feel environment for Windows. a DLL (cygwin1.dll) whi

wangxiaohong123的专栏 659

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

[Java] [ Android ] [ JNI ] [ JNI简单示例及参数类型 ]

1、Java代码的编写 1)、首先准备一个具有本地方法的Java文件HelloJNI ,编译生成HelloJNI.class, 代码内容如下: package com.lhy.comm; public class HelloJNI { static{ //加载生成的HelloJNI2.dll System.loadLibrary(&quot;HelloJNI2&quot;...

Hendy_Raw的博客 268

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

JNI接口简单示例

JNI是Java native interface的简写,可以译作Java原生接口。Java可以通过JNI调用C/C++的库,这对于那些对性能要求比较高的Java程序无疑是一个福音。 下面我就用JNI实现一个经典的“Hello World”程序。该程序在Java中通过JNI调用c函数实现“Hello World”的输出。创建该程序分为以下步骤: 1、创建一个Java程序(HelloWorld.ja...

Android/Linux驱动开发传帮带学习,让驱动入门门槛更低! 5139

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

逆向工程 --- Android JNI,从一个简单示例开始

通过比较两个反编译器,还是ghidra厉害,ida错误多且可读性差,但是ghidra有一个重大错误,返回值是空。还是建议使用ghidra的反编译功能。而且ghidra支持多个指令集的反编译,ida只支持x86。安卓支持很多不同cpu框架上运行,但是随着不断的发展淘汰了mips和arm32位,目前arm64位和x86成为了主流支持cpu。通过分析指令集ret,发现没有正确读取w0的值,属于软件缺陷。之后的分析在不说明的情况下默认是ghidra。我们分析一下错误如何产生的。对arm64的二进制分析。

cnzzs的博客 1011

windows下java调用JNI简单示例

Java JNI(Java Native Interface)是一种用于在Java程序中调用本地代码的技术。

kevinlcsdn的博客 933
ELETE
博客等级 码龄15年 0粉丝 1原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值