文档章节

JNIEnv说明

wangjian19
 wangjian19
发布于 2014/02/21 16:52
字数 774
阅读 353
收藏 5
点赞 0
评论 0

JavaVM接口

第一种方式,在加载动态链接库的时候,JVM会调用JNI_OnLoad(JavaVM* jvm, void* reserved)(如果定义了该函数)。第一个参数会传入JavaVM指针。

第二种方式,在native code中调用JNI_CreateJavaVM(&jvm, (void**)&env, &vm_args)可以得到JavaVM指针。

两种情况下,都可以用全局变量,比如JavaVM* g_jvm来保存获得的指针以便在任意上下文中使用。

Android系统是利用第二种方式Invocation interface来创建JVM的。

JNIEnv接口

需要强调的是JNIEnv是跟线程相关的。

在native method中,JNIEnv作为第一个参数传入。那么在JNIEnv不作为参数传入的时候,该如何获得它?

JNI提供了两个函数:

(*jvm)->AttachCurrentThread(jvm, (void**)&env, NULL)

 (*jvm)->GetEnv(jvm, (void**)&env, JNI_VERSION_1_2)

 两个函数都利用JavaVM接口获得JNIEnv接口,上面已经讲到如何获得JavaVM接口。

 JNI规范也说明,可以将获得JNIEnv封装成一个函数。

1
2
3
4
5
6
JNIEnv* JNU_GetEnv()
{
             JNIEnv* env;
             (*g_jvm)->GetEnv(g_jvm, (         void         **)&env, JNI_VERSION_1_2);
             return          env;
}

Java通过JNI机制调用c/c++写的native程序。c/c++开发的native程序需要遵循一定的JNI规范,下面的例子就是一个JNI函数声明:

JNIEXPORT jint JNICALL Java_jnitest_MyTest_test
  (JNIEnv 
* env, jobject obj, jint arg0);

JVM负责从Java Stack转入C/C++ Native Stack。当Java进入JNI调用,除了函数本身的参数(arg0),会多出两个参数:JNIEnv指针和jobject指针。
JNIEnv指针是JVM创建的,用于Native的c/c++方法操纵Java执行栈中的数据,比如Java Class, Java Method等。
首先,JNI对于JNIEnv的使用, 提供了两种语法: c语法以及c++语法,如下:
c语法:

jsize len = (*env)->GetArrayLength(env,array);

c++语法:

jsize len =env->GetArrayLength(array);

(注:由于C语言并不支持对象的概念,所以C语法中需要把env作为第一个参数传入,类似于C++的隐式参数this指针).

对于JNIEnv *env来说,在C中调用:

(*env)->NewStringUTF(env, "Hello from JNI!");

而在C++中如果按照上述调用则会发生'base operand of '->' has non-pointer type '_JNIEnv''错误,需要如下调用:

env->NewStringUTF("Hello from JNI!");

原因:参见jni.h中对于JNIEnv的定义:

#if defined(__cplusplus)

typedef _JNIEnv JNIEnv;

#else

typedef const struct JNINativeInterface* JNIEnv;

#endif
另外: JNIEnv有几个设计的原则:
第一、JNIEnv指针被设计成了Thread Local Storage(TLS)变量,也就是说每一个Thread, JNIEnv变量都有独立的Copy。你不能把Thead#1使用的JNIEnv传给Thread#2使用。

第 二、JNIEnv中定义了一组函数指针,c/c++ Native程序是通过这些函数指针操纵Java数据。这样设计的好处是:你的c/c++ 程序不需要依赖任何函数库,或者DLL。由于JVM可能由不同的厂商实现,不同厂商有自己不同的JNI实现,如果要求这些厂商暴露约定好的一些头文件和 库,这不是灵活的设计。
而且使用函数指针表的另外一个好处是: JVM可以根据启动参数动态替换JNI实现。


© 著作权归作者所有

共有 人打赏支持
wangjian19
粉丝 15
博文 50
码字总数 101397
作品 0
深圳
高级程序员
jni循环调用java接口发生崩溃

C本地接口 JNIEnv* jniEnv = NULL; jclass TestProvider = NULL; jobject mTestProvider = NULL; void CtoJavaInit(void){ TestProvider = (jniEnv)->FindClass(jniEnv,"com/example/jni/C2......

fcsong000833 ⋅ 2013/10/27 ⋅ 17

Java中JNI的使用详解第二篇:JNIEnv类型和jobject类型的解释

上一篇说的是一个简单的应用,说明JNI是怎么工作的,这一篇主要来说一下,那个本地方法sayHello的参数的说明,以及其中方法的使用 首先来看一下C++中的sayHello方法的实现: [cpp] view plai...

zhangyujsj ⋅ 2015/08/23 ⋅ 0

jni数据类型

在Java中有两类数据类型:primitive types,如,int, float, char;另一种为reference types,如,类,实例,数组。 注意:数组,不管是对象数组还是基本类型数组,都作为reference types存在...

wangjian19 ⋅ 2014/02/22 ⋅ 0

基于 Android NDK 的学习之旅----- C调用Java

许多成熟的C引擎要移植到Android 平台上使用 , 一般都会 提供 一些接口, 让Android sdk 和 jdk 实现。 下文将会介绍 C 如何 通过 JNI 层调用 Java 的静态和非静态方法。 1、主要流程 1、 新建...

LiSteven ⋅ 2013/03/19 ⋅ 0

「游戏引擎Mojoc」(10)Android NDK通用JNI调用Java代码封装

Mojoc提供了一个通用的工具类,来调用Android Java代码,以实现特定平台的功能。这个工具类封装了JNI使用的繁琐细和上下文对象的获取,提供了简单直接的API专注于Java类和方法的访问,并且实...

scottcgi ⋅ 05/20 ⋅ 0

学习——>JNI设置C++与java的结合(2)

我们可以看到其中有四个函数声明, Java完整类名方法名, 完整类名包括了包名, 例如demo.Sample1是完整类名, 对应的这里就是demoSample1. 在注释中我们可以看到这样一个东西 Signature, 这个是...

home-kevin ⋅ 2014/01/07 ⋅ 0

JNI知识(一)概述

1 JNI概述 JNI是java native interface的缩写,是用来从java调用C++/C代码,也可以从C++/C调用Java代码。 在jni.h中可以看到 class JvJavaVM { public: const struct JNIInvokeInterface *fu...

yixinuestc ⋅ 2014/03/04 ⋅ 0

ANDROID JNI之JAVA域与c域的互操作

本文讲述AndroidJava域与C域互操作:Java域调用c域的函数;c域访问Java域的属性和方法;c域生成的对象的保存与使用。重点讲解c域如何访问Java域。 虽然AndroidJNI实现中,c实现与c++实现是有...

垂盆草 ⋅ 2012/10/13 ⋅ 0

深入了解android平台的jni---图像灰度化处理

一、涉及到的jni编程知识 Java基本类型的数组,在JNI中都是jArray的类型格式。具体类型如下: typedef jarray jbooleanArray; typedef jarray jbyteArray; typedef jarray jcharArray; type...

mfcai ⋅ 2013/07/01 ⋅ 1

C和C++函数时的JNI使用区别

Java调用C和C++函数时的JNI使用区别: 注意:jni.h头文件中对于*.c & .cpp采用不同的定义 在C的定义中,env是一个两级指针,而在C++的定义中,env是个一级指针 C形式需要对env指针进行双重defer...

zhangyujsj ⋅ 2015/08/23 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

android -------- 颜色的半透明效果配置

最近有朋友问我 Android 背景颜色的半透明效果配置,我网上看资料,总结了一下, 开发中也是常常遇到的,所以来写篇博客 常用的颜色值格式有: RGB ARGB RRGGBB AARRGGBB 这4种 透明度 透明度...

切切歆语 ⋅ 8分钟前 ⋅ 0

CentOS开机启动subversion

建立自启动脚本: vim /etc/init.d/subversion 输入如下内容: #!/bin/bash## subversion startup script for the server## chkconfig: 2345 90 10# description: start the subve......

随风而飘 ⋅ 12分钟前 ⋅ 0

Nginx + uwsgi @ubuntu

uwsgi 安装 sudo apt-get install python3-pip # 注意 ubuntu python3默认没有安装pippython3 -m pip install uwsgi 代码(test.py) def application(env, start_response): start_res......

袁祾 ⋅ 12分钟前 ⋅ 0

版本控制工具

CSV , SVN , GIT ,VSS

颖伙虫 ⋅ 15分钟前 ⋅ 0

【2018.06.19学习笔记】【linux高级知识 13.1-13.3】

13.1 设置更改root密码 13.2 连接mysql 13.3 mysql常用命令

lgsxp ⋅ 23分钟前 ⋅ 0

LVM

LVM: 硬盘划分分区成物理卷->物理卷组成卷组->卷组划分逻辑分区。 1.磁盘分区: fdisk /dev/sdb 划分几个主分区 输入t更改每个分区类型为8e(LVM) 使用partprobe生成分区的文件:如/dev/sd...

ZHENG-JY ⋅ 51分钟前 ⋅ 0

彻底删除Microsoft Office的方法

参照此链接彻底删除Office https://support.office.com/zh-cn/article/%e4%bb%8e-pc-%e5%8d%b8%e8%bd%bd-office-9dd49b83-264a-477a-8fcc-2fdf5dbf61d8?ui=zh-CN&rs=zh-CN&ad=CN......

Kampfer ⋅ 今天 ⋅ 0

大盘与个股之间关系

大盘走多:积极出手 顺势加码 大盘走空: 少量出手 退场观望 大盘做头:逆势减码 少量操作 大盘做底 : 小量建仓 小量试单

guozenhua ⋅ 今天 ⋅ 0

Day16 LVM(逻辑卷管理)与磁盘故障小案例

lvm详解 简述 LVM的产生是因为传统的分区一旦分区好后就无法在线扩充空间,也存在一些工具能实现在线扩充空间但是还是会面临数据损坏的风险;传统的分区当分区空间不足时,一般的解决办法是再...

杉下 ⋅ 今天 ⋅ 0

rsync实现多台linux服务器的文件同步

一、首先安装rsync,怎样安装都行,rpm,yum,还是你用源码安装都可以。因为我用的是阿里云的ESC,yum install rsync就ok了。 二、配置rsync服务 1.先建立个同步数据的帐号 123 groupadd r...

在下头真的很硬 ⋅ 今天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部