jni直接转byte_JNI再探之JNI 数据类型及Java与C++之间互调

这篇博客详细介绍了JNI,包括JNI数据类型、映射表、方法签名以及在Android Studio 3.0中如何打印日志。内容涵盖Java调用C/C++本地函数、C/C++访问Java层属性和方法的多种方式,解析了JNI函数的使用细节。
摘要由CSDN通过智能技术生成

5b3c4786caf423a640711d835ffa8a46.png

JNI

什么是JNI

JNI,全称Java NativeInterface,是一种为Java编写本地方法和JVM嵌入本地应用程序标准的应用程序接口,它允许运行在JVM上的Java代码能够与C/C++实现的本地库进行交互。

JNI 数据类型

Java中有两种类型:基本数据类型(int、float、char等)和引用类型(类、对象、数组等)。 JNI定义了一个C/C++类型的集合,集合中每一个类型对应于Java中的每一个类型,其中,对于基本类型而言,JNI与Java之间的映射是一对一的,比如Java中的int类型直接对应于C/C++中的jint;而对引用类型的处理却是不同的,JNI把Java中的对象当作一个C指针传递到本地函数中,这个指针指向JVM中的内部数据结构,而内部数据结构在内存中的存储方式是不可见的,本地代码必须通过在JNIEnv中选择适当的JNI函数来操作JVM中的对象。比如,对于java.lang.String对应的JNI类型是jstring,但本地代码只能通过GetStringUTFChars这样的JNI函数来访问字符串的内容。

JNI映射表

| Java 类型 | JNI本地类型 |方法签名 | 描述 | | ------ |------|------|------| | boolean | jboolean | Z | unsigned 8 bits| | byte | jbyte | B |signed 8 bits| | char | jchar | C |unsigned 16 bits| | short | jshort | S | signed 16 bits | | int | jint | I | signed 32 bits | | long | jlong | J | signed 64 bits | | float | jfloat | F | 32bits | | double | jdouble | D | 64bits | | void | Void | V | - |

方法签名

由于Java支持方法重载,在JNI访问Java层方法时仅靠函数名是无法唯一确定一个方法,因此JNI提供了一套签名规则(如:Z、B、[Z等),用一个字符串来唯一确定一个方法,其规则:(参数1类型签名参数2类型签名…)返回值类型签名,比如Java方法long getDeviceId(int n, String s, int[] arr)、long getDeviceId(int n)的类型签名分别为(ILjava/lang/String;[I)J、(I)J。 1. 基本类型: boolean ->Z,byte-> B,char -> C,short-> S,int->I,long->J,float-> F,double->D,void -> V; 2. 如果是类的类型:L+类全名,类名中的.用/代替,比如java.lang.String就是Ljava/lang/String; 3. 如果是数组类型:则在前面加上 然后加类型签名,几位数组就加几个,比如int[]->[I,boolean[][]->[[Z,java.lang.Class[] -> [Ljava/lang/Class; 可以通过javap -s来打印该方法的签名

Example:
public static native String getName();
public static native int calculate(int a,int b);

通过Rebuild Project才会在app中的intermediates目录下javac/debug生成class文件,找到 类到地址 然后右键打开命令行

ea67944829a8c9109767adc895719a7e.png

在命令行输入 javap -s JNIUtils.class 即可获取到2个方法到签名,我这里是JNIUtils获取的两个签名如下:

警告: 二进制文件JNIUtils包含com.example.nativejnidemo.JNIUtils
Compiled from "JNIUtils.java"
public class com.example.nativejnidemo.JNIUtils {
    
  public com.example.nativejnidemo.JNIUtils();
    descriptor: ()V
  public static native java.lang.String getName();
//
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值