JNI的目的是可以使用C/C++完成部分逻辑,一方面 代码复用,避免重复劳动。另外一方面有些东西还是C语言处理起来比较方便,比如和底层驱动程序打交道等等。JAVA调用C/C++方法,就要把参数传递给C/C++代码,或者C/C++代码可以获取到JVM的内存数据, JAVA和C之间可以数据交互。

1、数据类型

JAVA和C/C++之间传递数据,就要有相互对应的数据类型。

首先是基本类型,每种语言都会有的,所以直接用typedef 定义完成:

typedef unsigned char jboolean;

typedef unsigned short jchar;

typedef short jshort;

typedef float jfloat;

typedef double jdouble;

typedef long jint;

typedef __int64 jlong;

typedef signed char jbyte;

在java里除此之外的对象都是继承于java.lang.Object。所以JNI里也定义了一个jobject的结构体。

这样java所有的对象都可以用jobject传递。

参考官方文档:http://docs.oracle.com/javase/7/docs/technotes/guides/jni/spec/types.html

为了方便使用,JNI还定义了一些特殊的常用对象,比如类对象jclass, 异常对象jthrowable,数组对象jarray等等。

不过这些对象都是空的,也就是你不通过调用它们的方法的方式去调用java里的方法。

如果想调用它们的方法,或者获取它们的一些属性。你需要把它们当作参数,传递给JNIENV的对应api。

比如你想获取一个数组的长度,你需要调用JNIENV的GetArrayLength方法:

jsize GetArrayLength(jarray array)

2、JNIEnv指针。

在JNI自动生成的代码里,函数参数,必须有一个JNIEnv *指针,这个就是用来调用JVM的方法的。

关于JNIENV的定义可以查看jni.h。你会发现它是一个struct。

如果你是C++语言实现,那么它这个struct就相当于一个class,大家知道在C++里,struct和class是没有多大区别的,唯一的区别就默认访问权限的问题。这都不是很重要。重要的是struct里可以定义方法和属性。JNIENV里提供了一系列的api,供使用者调用。

如果是C语言实现的呢,会发现JNIENV也是一个struct,但是C语言是一种面向过程的语言,他没有对象的概念,它的struct里是不能定义方法的。但是有一个叫“函数指针”的东西,可以让C语言实现一种面向对象的感觉,JNI就是这样做到的,它在struct里定义了一系列的函数指针,用于访问JVM。

这样无论C,还是C++。都可以使用JNIENV的api访问jvm。

jni.h里是通过__cplusplus控制的

都有那些方法,可以查看oracle官方文档:

http://docs.oracle.com/javase/7/docs/technotes/guides/jni/spec/functions.html

3、共享内存。

Java除了提供参数传递的方式,和C/C++交互数据之外,还有一种共享数据的方式就是共享内存。Java里可以直接申请JVM的堆外的内存,和C语言共用。

那就是java里的一个特殊类:ByteBuffer,它的allocateDirect方法,可以直接在JVM之外的内存中开辟空间。

这种开辟内存的方式要比直接申请JVM堆内内存耗时多,所以这种方式一般用于使用比较频繁,可以重复使用的场景。

比如java和c之间有大量数据要交互,那么就可以使用ByteBuffer申请一块一定大小内存作为缓存。使用ByteBuffer可以大量减少JVM和C语言之间的内存copy产生的开销

下一篇学习ByteBuffer的实际使用。

java调c 申请内存_JAVA简单调用C/C++语言(JNI学习三)相关推荐

  1. java nio 堆外内存_Java堆外内存之突破JVM枷锁

    对于有Java开发经验的朋友都知道,Java中不需要手动的申请和释放内存,JVM会自动进行垃圾回收:而使用的内存是由JVM控制的. 那么,什么时机会进行垃圾回收,如何避免过度频繁的垃圾回收?如果JVM ...

  2. java调c的接口_Java调用C接口的简单示例

    Java调用C接口的简单示例 正好需要用到Java调用dll里的C接口,想到自己做个简单的例子.我们可能需要自己生成dll文件,下边介绍一下,详细的步骤.主要参考https://blog.csdn.n ...

  3. java如何调c 的接口_JAVA中调用C语言接口

    写一个Java类,在这个类中包含了需要调用的本地方法的描述. //WinMsgBox.java package edu.netcom.jni; public class WinMsgBox  { st ...

  4. 我的世界java占用太多内存_Java 进程占用内存过多,幕后元凶原来是线程太多

    那天中午吃饭,一个同事说,那个项目组的人快气死我了,程序有问题,早晨在群里@了他们,到中午才回消息,然后竟然还说他们的程序没有问题,是我们这边调用的太频繁了. 简直想笑. 背景说明 我们当前这个系统和 ...

  5. java克隆 是否节省内存_Java编程时如何节省内存,效率高

    很多人都说"Java完了,只等着衰亡吧!",为什么呢?最简单的的例子就是Java做的系统时非常占内存!一听到这样的话,一定会有不少人站出来为Java辩护,并举出一堆的性能测试报告来 ...

  6. java jsp中的日历表_JAVA简单的日历程序

    JAVA简单的日历程序 作者:未知    文章来源:www.jspcn.net 发布日期:2005年01月19日 /**以下是日历的代码程序 有疑问 回信 ycj@18e.net **/ //Cale ...

  7. java实现分页打印功能_Java简单高效实现分页功能

    今天想说的就是能够在我们操作数据库的时候更简单的更高效的实现,现成的crud接口直接调用,方便快捷,不用再写复杂的sql,带吗简单易懂,话不多说上方法 1.utils.java工具类中的方法 /** ...

  8. Java吃CPU还是内存_Java中的CPU占用高和内存占用高的问题排查

    下面通过模拟实例分析排查Java应用程序CPU和内存占用过高的过程.如果是Java面试,这2个问题在面试过程中出现的概率很高,所以我打算在这里好好总结一下. 1.Java CPU过高的问题排查 举个例 ...

  9. java 反射无参方法_java 反射 调用无参数方法?

    通过Java反射调用无参数方法,这是个测试用的例子,通过反射调用对象的方法,代码如下: import java.lang.reflect.Method; import java.lang.reflec ...

最新文章

  1. 如何利用python爬虫获取网易云音乐某个歌手简介_Python 爬虫获取网易云音乐歌手信息...
  2. 说明 modbus 台达ups_改造机架式UPS风扇,让机柜内最大噪音污染源安静下来
  3. 界面设计 java_Java界面设计
  4. python去除视频马赛克_马赛克是否无法逆转?Python简单消除,看片无忧!
  5. sshpass做秘钥分发,ansible做自动化运维工具
  6. 把zabbix图形整合至运维平台
  7. A. 解决运行php文件出现乱码的问题
  8. bio linux 创建_Linux 五种IO模型
  9. GitHub添加SSH-key的步骤
  10. Java实现常用的三种加密算法详解
  11. 龙华大浪注塑加工中模具原理及组成
  12. Django测试文件——tests.py
  13. Flutter 接入iOS苹果内购支付踩坑过程
  14. 《平凡的世界》读后感 — 孙少平篇
  15. 为什么要努力读书学习,一位清华妈妈总结了7条,太到位了
  16. php 代替each()函数写法
  17. DES加解密算法原理详解与实现
  18. 项目方按本纲要编制商业计划书范本
  19. 深度操作系统 机器学习_深度学习如何构建情感聊天机器人,第2部分对话系统...
  20. 前后端分离项目,vue+uni-app+php+mysql教室预约小程序系统 开题报告

热门文章

  1. 使用bat向文件的第一行中写入内容
  2. batch echo 输出空格(空行 空白行)
  3. 【Hadoop】同步集群时间
  4. 【Oracle】DBMS_STATS.GATHER_TABLE_STATS
  5. 安装centos后 启动mysqld显示mysqld: 未被识别的服务 解决方法
  6. 使用jQuery的插件qrcode生成二维码(静态+动态生成)及常见问题解决方法
  7. 安全的API接口解决方案
  8. IEnumerable和使用收益回报的递归
  9. 电脑c盘满了怎么清理
  10. python口号_编程语言的口号