JNI 数据类型转换(转)

JNI 定义了一系列基本数据类型和引用数据类型与java想对应。
 
1、基本数据类型
下面一张表是描述了 Java 基本数据类型和JNI中基本数据类型的相对应关系已经占用空间大小。

JNI 数据类型转换 - hero_213 - hero_213的博客

随便观察就能发现,其实就基本数据类型而已,JNI基本数据类型只是比Java基本数据类型前多了个’j’而已
当然,JNI中还有个Java中没有的jsize,定义如下:
typedef jint jsize;
其实jsize整型是用来描述基本指标和大小,没有什么神秘的。

 

2、引用数据类型
JNI 引用类型 与 Java 的对应关系 如下 树层次图:

JNI 数据类型转换 - hero_213 - hero_213的博客

 
跟java一样,jobject 是所有引用类型的 父亲。看看是不是很容易理解 ?呵呵.关于jthrowable,JNI也是有线程概念的.


3、 The jvalue Type
Jvalue 是基本数据类型和引用数据类型的集合,它的定义如下:
typedef union jvalue {
    jboolean z;
    jbyte    b;
    jchar    c;
    jshort   s;
    jint     i;
    jlong    j;
    jfloat   f;
    jdouble  d;
    jobject  l;
} jvalue;


Java类型和本地类型对应  
  在如下情况下,需要在本地方法中应用java对象的引用,就会用到类型之间的转换:
  1)java方法里面将参数传入本地方法;
  2)在本地方法里面创建java对象;
  3)在本地方法里面return结果给java程序。
  分为如下两种情况:
  Java原始类型
  像booleans、integers、floats等从Java程序中传到本地方法中的原始类型可以直接使用,下面是java中的原始类型和本地方法中的类型的对应:
  Java类型  本地类型  字节(bit)
  boolean   jboolean   8, unsigned
  byte    jbyte    8
  char    jchar    16, unsigned
  short    jshort    16
  int     jint     32
  long    jlong    64
  float    jfloat    32
  double   jdouble   64
  void    void     n/a
  也就是说如果我在方法中传进去了一个boolean的参数的话,那么我在本地方法中就有jboolean类型与之对应。同理,如果在本地方法中return一个jint的话,那么在java中就返回一个int类型。
  Java对象
  Java对象做为引用被传递到本地方法中,所有这些Java对象的引用都有一个共同的父类型jobject(相当于java中的Object类是所有类的父类一样)。下面是JNI实现的一些jobject的子类:


  4.本地方法中访问java程序中的内容
  1)访问String对象:
  从java程序中传过去的String对象在本地方法中对应的是jstring类型,jstring类型和c中的char*不同,所以如果你直接当做 char*使用的话,就会出错。因此在使用之前需要将jstring转换成为c/c++中的char*,这里使用JNIEnv的方法转换。下面是一个例子:
  代码3:
  JNIEXPORT jstring JNICALL Java_Prompt_getLine
  (JNIEnv *env, jobject obj, jstring prompt)
  {
  char buf[128];
  const char *str = (*env)->GetStringUTFChars(env, prompt, 0);
  printf("%s", str);
  (*env)->ReleaseStringUTFChars(env, prompt, str);
  这里使用GetStringUTFChars方法将传进来的prompt(jstring类型)转换成为UTF-8的格式,就能够在本地方法中使用了。
  注意:在使用完你所转换之后的对象之后,需要显示调用ReleaseStringUTFChars方法,让JVM释放转换成UTF-8的string的对象的空间,如果不显示的调用的话,JVM中会一直保存该对象,不会被垃圾回收器回收,因此就会导致内存溢出。
  下面是访问String的一些方法:
  ◆GetStringUTFChars将jstring转换成为UTF-8格式的char*
  ◆GetStringChars将jstring转换成为Unicode格式的char*
  ◆ReleaseStringUTFChars释放指向UTF-8格式的char*的指针
  ◆ReleaseStringChars释放指向Unicode格式的char*的指针
  ◆NewStringUTF创建一个UTF-8格式的String对象
  ◆NewString创建一个Unicode格式的String对象
  ◆GetStringUTFLengt获取UTF-8格式的char*的长度 
  ◆GetStringLength获取Unicode格式的char*的长度
  2) 访问Array对象:
  和String对象一样,在本地方法中不能直接访问jarray对象,而是使用JNIEnv指针指向的一些方法来是用。
  
  访问Java原始类型数组:
  1)获取数组的长度:
  代码4:
  JNIEXPORT jint JNICALL Java_IntArray_sumArray
  (JNIEnv *env, jobject obj, jintArray arr)
  {
  int i, sum = 0;
  jsize len = (*env)->GetArrayLength(env, arr);
  如代码4所示,这里获取数组的长度和普通的c语言中的获取数组长度不一样,这里使用JNIEvn的一个函数GetArrayLength。
  
  2)获取一个指向数组元素的指针:
  代码4:
  jint *body = (*env)->GetIntArrayElements(env, arr, 0);
  使用GetIntArrayElements方法获取指向arr数组元素的指针,注意该函数的参数,第一个是JNIEnv,第二个是数组,第三个是数组里面第三个是数组里面开始的元素
  
  3)使用指针取出Array中的元素
  
  代码5:
  for (i=0; i<len; i++) {
  sum += body[i];
  }
  这里使用就和普通的c中的数组使用没有什么不同了
  4)释放数组元素的引用
  代码6: 
  (*env)->ReleaseIntArrayElements(env, arr, body, 0);
  和操作String中的释放String的引用是一样的,提醒JVM回收arr数组元素的引用。
  这里举的例子是使用int数组的,同样还有boolean、float等对应的数组。
  获取数组元素指针的对应关系:
  函数            数组类型
  GetBooleanArrayElements   boolean
  GetByteArrayElements    byte
  GetCharArrayElements    char
  GetShortArrayElements    short
  GetIntArrayElements     int
  GetLongArrayElements    long
  GetFloatArrayElements    float
  GetDoubleArrayElements   double
  
  释放数组元素指针的对应关系:
  Function            Array Type
  ReleaseBooleanArrayElements   boolean
  ReleaseByteArrayElements    byte
  ReleaseCharArrayElements    char
  ReleaseShortArrayElements    short
  ReleaseIntArrayElements     int
  ReleaseLongArrayElements    long
  ReleaseFloatArrayElements    float
  ReleaseDoubleArrayElements   double
  
  访问自定义Java对象数组
  
  The JNI provides a separate set of functions to access elements of object arrays. You can use these functions to get and set individual object array elements.
  
  Note: You cannot get all the object array elements at on

ce.
  
  GetObjectArrayElement returns the object element at a given index.
  
  SetObjectArrayElement updates the object element at a given index.
  
  3) 访问Java对象的方法:
  
  在本地方法中调用Java对象的方法的步骤:
  
  ①.获取你需要访问的Java对象的类:
  
  jclass cls = (*env)->GetObjectClass(env, obj);
  
  使用GetObjectClass方法获取obj对应的jclass。
  
  ②.获取MethodID:
  
  jmethodID mid = (*env)->GetMethodID(env, cls, "callback", "(I)V");
  
  使用GetMethdoID方法获取你要使用的方法的MethdoID。其参数的意义:
  
  env??>JNIEnv
  
  cls??>第一步获取的jclass
  
  "callback"??>要调用的方法名
  
  "(I)V"??>方法的Signature
  
  ③.调用方法:
  
  (*env)->CallVoidMethod(env, obj, mid, depth);
  
  使用CallVoidMethod方法调用方法。参数的意义:
  
  env??>JNIEnv
  
  obj??>通过本地方法穿过来的jobject
  
  mid??>要调用的MethodID(即第二步获得的MethodID)
  
  depth??>方法需要的参数(对应方法的需求,添加相应的参数)
  
  注:这里使用的是CallVoidMethod方法调用,因为没有返回值,如果有返回值的话使用对应的方法,在后面会提到。
  
  方法的Signature
  
  方法的Signature是由方法的参数和返回值的类型共同构成的,下面是他们的结构:
  
  "(argument-types)return-type"
  
  其中Java程序中参数类型和其对应的值如下:
  
  Signature  Java中的类型
  Z       boolean
  B       byte
  C       char
  S       short
  I       int
  J       long
  F       float
  D       double
  L fully-qualified-class;   fully-qualified-class
  
  [ type  type[]
  
  ( arg-types ) ret-type  method type
  一个Java类的方法的Signature可以通过javap命令获取:
  javap -s -p Java类名
  给调用的函数传参数:
  通常我们直接在methodID后面将要传的参数添加在后面,但是还有其他的方法也可以传参数:
  CallVoidMethodV可以获取一个数量可变的列表作为参数;
  CallVoidMethodA可以获取一个union。
  调用静态方法:
  就是将第二步和第三步调用的方法改为对应的:
  GetStaticMethodID获取对应的静态方法的ID
  CallStaticIntMethod调用静态方法
  调用超类的方法:
  用的比较少,自己看啦。^_^。
  4)访问Java对象的属性:
  访问Java对象的属性和访问Java对象的方法基本上一样,只需要将函数里面的Method改为Field即可

jbytearray转c++byte数组 byte * arrayBody = env->GetByteArrayElements(data,0);  jsize theArrayLengthJ = env->GetArrayLength(data);  BYTE * starter = (BYTE *)arrayBody;  jbyteArray 转 c++中的BYTE[] //jbytearray strIn 阅读详情

相关推荐

从零开始:用摩尔线程S4000运行开源AI项目的完整流程

本文详细介绍了如何使用摩尔线程S4000 GPU从零开始运行开源AI项目的完整流程,包括硬件选择、驱动安装、容器化环境配置以及典型AI项目的实战部署。通过性能优化技巧,显著提升推理速度,适合开发者快速上手国产GPU的AI应用开发。

weixin_29231725的博客 581

Java基础知识——JNI入门介绍(下)

http://java.chinaitlab.com/JDK/36678.html 3.Java类型和本地类型对应      在如下情况下,需要在本地方法中应用java对象的引用,就会用到类型之间的转换:      1)java方法里面将参数传入本地方法;      2)在本地方法里面创建java对象;      3)在本地方法里面return结果给java程序。 ...

tansitongba 745

Windows/Mac/Linux三系统保姆级教程:用llama.cpp将safetensors模型转gguf格式(附常见错误解决)

本文提供Windows、Mac和Linux系统下使用llama.cpp将safetensors模型转换为gguf格式的详细教程,涵盖环境配置、转换原理及常见错误解决方案。通过跨平台兼容性处理,帮助开发者高效完成模型格式转换,优化边缘计算性能。

weixin_29227425的博客 270

String 与 char* 相互转换

转载至:https://blog.youkuaiyun.com/qq_18410319/article/details/90487796 一、string->char* 1、将string转char*,可以使用string提供的c_str()或者data()函数。其中c_str()函数返回一个以'\0'结尾的字符数组,而data()仅返回字符串内容,而不含有结束符'\0'。 2、const char* c_str(); c_str()函数返回一个指向C字符串的指针,该指针指向内存内容和string 相同。

Vertira的博客 1万+

auto.js梦幻西游游戏脚本,梦幻西游脚本开发思路

本篇文章给大家谈谈梦幻西游脚本用什么语言写,以及auto.js梦幻西游游戏脚本,希望对各位有所帮助,不要忘了收藏本站喔。

npy199331的博客 1939

为ESXI Host添加v3700 FC存储

物理环境: ESXI Host version 5.1.0 Brocade SAN Switch v3700 Storage 存储和ESXI Host分别用光纤线连接在SAN交换机上 1.查询ESXI Host 的WWN号: 2. SAN交换机上查询存储的WWPN号 SAN交换机: 3.建立zone,添加到cfg文件中 brocade8Gb

haoshuwei531024的专栏 7562

02-1 jstring与char*,string的转换

jstring与char*的转换 一、 jstring ==> char* jstring jstr; const char *str = (*env)->GetStringUTFChars(env, prompt, 0); printf("%s", str); (*env)->ReleaseStringUTFChars(env, prompt, str);...

studyforelectronics的博客 596

MySQL常见面试题汇总(建议收藏!!!)

目录一、索引相关(1)什么是索引?(2)索引是个什么样的数据结构呢?(3)为什么使用索引?(4)Innodb为什么要用自增id作为主键?(5)Hash 索引和 B+ 树索引有什么区别或者说优劣呢?(6)什么是聚簇索引(6)非聚簇索引一定会回表查询吗?(6)聚簇索引和非聚簇索引的区别(6)MyISAM和InnoDB实现B+树索引方式的区别是什么?(6)MySQL中有四种索引类型,可以简单说说吗?(6)覆盖索引是什么?(6)联合索引是什么?为什么需要注意联合索引中的顺序?(6)创建的索引有没有被使用到?或者说怎

蔡政洁的博客 7万+

JNI将jstring转换成char* string

Android开发NDK或C++和Java交互是经常用到jstring转换成C++想要的string或char*以下例子和使用方法。 #define FUNC_CPY_JSTRING(name,len,jstr) \ char name[len+1] = {0}; \ if(jstr != NULL)\ { \ const char* __tmp_dn__ = env-&gt;Ge...

宇宙精英 2909

手把手教你用Copilot插件在Obsidian里免费接入DeepSeek-R1(附硅基流动API密钥获取)

本文详细介绍了如何通过Copilot插件在Obsidian中免费接入DeepSeek-R1模型,实现智能知识管理。从硅基流动API密钥获取到插件配置,再到高级功能调优和实战应用技巧,手把手教你打造AI驱动的个人知识库。

weixin_33686714的博客 2794

ANSYS MAXWELL内置式永磁同步电机(IPMSM)转矩最大时输入电流相位的确定

1.在转子转速为零时看一个周期内的转矩变化

qq_41752507的博客 6517

jni直接转byte_Android JNI 数据类型转换

基本数据类型转换Java类型别名  C++本地类型  字节(bit)boolean jboolean unsignedchar  8,unsignedbyte jbyte signedchar    8char jchar unsignedshort   ...

weixin_42423349的博客 766

MIMIC数据库简介

一 、MIMIC简介 MIMIC(Medical Information Mart for Intensive Care),是一个大型的公开数据库。该数据库记录了2001年至2019年期间贝斯以色列女狄肯斯医疗中心重症监护病房患者的相关数据,拥有4万多名患者的医疗健康数据和记录。 MIMIC数据库记录了人口统计学信息,如病人的性别、身高、宗教等情况。记录了实验室检验信息,如血常规,肝功能,肾功能等实验室检测数据。记录了患者的用药信息,如高血压患者服用了治疗高血压类药物等。记录了护理人员以及患者的护理级别等。

越努力 越幸运 1万+

JNI与C/C++数据类型的转换(转)

字符数组与jbyteArrayjbyteArray转字符数组int byteSize = (int) env-&gt;GetArrayLength(jbyteArrayData); //jbyteArrayData是jbyteArray类型的数据 unsigned char* data = new unsigned char[byteSize + 1]; env-&gt;GetByteArray...

萧萧萧萧 3421

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

Android JNI 数据类型转换

本文转自https://www.cnblogs.com/likwo/archive/2012/05/22/2512483.html 具体内容本人未验证。 基本数据类型转换 Java类型别名  C++本地类型  字节(bit)boolean jboolean unsignedchar  8,unsignedbyte...

格物致知的专栏 [音视频编解码 网络协议 计算机视觉 计算机图形学 图像理解 语音识别 机器学习 模拟电路 传感器] 351

RU DOS版、EFI版32bit/64bit BIOS常用工具

DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。

android底层开发学习笔记五(JNI机制上)

JNI 是 Java 语言的一个重要特性,它使得 Java 程序能够调用和被 C/C++ 程序调用,从而充分利用 Java 的跨平台特性和 C/C++ 的高性能特性。3)java如何调用c库中的Jni_onload函数,或者c库中的Jni_onload函数怎么知道是哪个类调用了Jni_onload函数。通过javah,利用.class文件生成JNI的.h文件(生成后的JNI头文件包含了java函数在JNI层的声明)1)实现原理:直接告诉native函数其在JNI中对应函数的指针(Jni_onload);

faye_li的博客 1732

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

JNI的某些数组和字符串类型转换(转)

JNICC++C#Windows jbytearray转c++byte数组  C代码   [c] view plaincopy jbyte * arrayBody = env->GetByteArrayElements(data,0);    jsize theArrayLengthJ = env->GetArrayLeng

老衲不出家 470

JNI - JAVA 数据类型转换

基本数据类型转换 在 Java 中传递的参数类型是 int,而在 JNI 中就成了 jint,这就涉及到 Java 到 JNI 的数据类型转换。 Java 类型 Native 类型 字节长度 boolean jboolean 8位 byte jbyte 8位 char jchar 16位 short jshort 16位 int jnit 32位 long jlong 64位 float jfloat 32位 double jdouble 64位 ...

TLuffy的博客 3156

Android jni/ndk编程二:jni数据类型转换(primitive,String,array)

前一篇文章中我们初步的认识了jni的相关概念,并通过静态和动态的方式体验了一把jni编程。这一片文章将进一步探究jni编程的基本知识,并且将重点集中在java数据类型映射到本地数据类型这一方面。

阳光玻璃杯 5983

JNI编程中数据类型转换的方法

问题描述 又要进行我的JNI编程之旅了 说实话 Java的运行效率低下的确是一个难以解决的问题 在JNI编程中 一个很常见的问题就是进行数据类型的转换 接下来Youki就会记录一下常见的数据转换方法

墨门 1493

C++和JNI的数据转换

如何使用JNI的一些基本方法和过程在网上多如牛毛,如果你对Jni不甚了解,不知道Jni是做什么的,如何建立一个基本的jni程序,或许可以参考下面下面这些文章: 利用VC++6.0实现JNI的最简单的例子  JNI入门教程之HelloWorld篇  SUN JNI Tutorial 这些资料的例子中,大多数只是输入一些简单的参数,获取没有参数。而在实际的使用过程中,往往需要对参数进行处理

happyq的专栏 802

jni中数据类型的转换问题

此文以c++为例(在jni中c++和c的写法有细微差异),这里我们将java层的string类型需要转换成C++识别的类型。看下面这段代码: JNIEXPORT void JNICALL Java_com_yunjian_ThirdParty_ThirdPartyManager_JoinGameNumberMK(JNIEnv *env,jobject thiz, jstring nIndexID

帅呆sky的博客 1313

java jni 数据类型转换_NDK开发 - JNI数据类型与Java数据类型映射关系

介绍完Android JNI的开发流程就要开始码代码了,不过在码代码前还是有必要了解下JNI数据类型与Java数据类型映射关系,直接开始写肯定会懵逼。在调用 Java native 方法将实参传递给 C/C++ 函数的时候,会自动将 java 形参的数据类型自动转换成 C/C++ 相应的数据类型,所以我们在写 JNI 程序的时候,必须要明白它们之间数据类型的对应关系。在 Java 语言中数据类型分...

weixin_39689428的博客 236

NDK/JNI 开发之 Java 类和 C 结构体互转示例

一、简介 JNI 开发中,常常会存在对应的 Java 类和 C 结构体需要互相转换。通过本实例学习和了解这个过程。 预备知识: JNI数据类型和类型描述符介绍:https://blog.youkuaiyun.com/afei__/article/details/80899758 JNI 方法及使用示例:https://blog.youkuaiyun.com/afei__/article/details/81016413......

阿飞的博客 9510
上一篇: Android中的几种网络请求方式
下一篇: JNI常用函数(转)
Li Chuan
博客等级 码龄14年 0粉丝 29原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值