从场景和需求梳理JNI接口

阅读: 评论:0

从场景和需求梳理JNI接口

从场景和需求梳理JNI接口


1 真实的情景和互动的对象

都有哪些Java和C交互的场景?真实的场景是: 1、一个C程序被系统加载并运行(比如) 2、C程序加载Java虚拟机并运行一个Java类(这个动作使用Invocation API接口) 3、有可能,这个运行的Java类需要加载一个C库(通过System.loadLibrary函数),C库代码和这个Java类互动,包括互相调用函数和访问变量(这个是通常所言的JNI,通过env指向的函数列表来实现相互操作)
其中第二个场景有互动需求,注意依赖关系是C加载Java。其中第三个场景有互动需求,注意依赖关系是Java加载C。
哪些可以互动?必须是某种实体。 C侧: 变量 函数 Java侧: 对象 对象的公有方法和变量 类的静态方法和静态变量
上述个体都可能成为互动的对象,只有方法或函数可以成为互动的发起者
至此我们理清楚了互动情景。下面我们来梳理互动的操作细节

2 第三个场景,Java代码加载C代码
根据场景来区分。先研究第三个场景,也即Java代码加载C代码。
2.1 可能的互动
Java代码加载C代码时可能出现的互动: Java访问C侧 看到的范例是Java调用C函数 Java可以访问C变量吗?未知,细节留待以后研究 C可以有全局或静态变量吗?可以 C可以重入吗?未知,取决于C侧代码设计
C访问Java侧 C可以通过JNI接口查找和访问Java侧类 C可以通过JNI接口调用Java侧类构造方法,用以生成对象 C可以通过JNI接口访问Java侧对象的变量和方法 C可以通过JNI接口访问Java侧类的静态变量和静态方法
2.2 Java访问C侧
Java侧访问C侧函数的找寻方法: 1、通过函数原型匹配,注意函数原型是通过函数名和其他信息一起组合生成的 2、通过注册函数直接强制链接。注意C库中的JNI_OnLoad()会被自动和首先调用,可以在其中注册和链接
函数原型样式: JNIEXPORT void JNICALL Java_HelloJNI_printHello(JNIEnv *, jobject, jstring)
JNIEnv指向JNI接口的功能函数表,表中各种函数往往用来转换数据,或者访问其他 如果是C++,可以省略掉这个参数 jobject指向调用的发出者,说明这里是对象发出对C的调用。如果是类的静态方法在调用C代码的话,这里是jclass。 jstring是一个参数示例

2.3 C访问Java侧
实质是,plain的C代码怎样访问用对象封装的Java元素 怎样访问一个Java类的变量和方法?首先是这些资源被编码了,并生成了签名,可以根据签名去索引。
可能的访问 C可以访问JNI接口函数,当然JNI接口函数也就是为C准备的 C可以通过JNI接口函数查找和访问Java侧类 C可以通过JNI接口函数调用Java侧类构造方法,用以生成对象 C可以通过JNI接口函数访问Java侧对象的变量和方法 C可以通过JNI接口函数访问Java侧类的静态变量和静态方法
有哪些因素在访问中需要考虑? 1、双方有不同的基本数据类型,包括各种char、int、long等等,需要使用一个统一的本地类型:jchar、jint、jlong 2、Java有类和对象的概念,还有String,但C只有plain string,因此C侧需要从Java对象中抽取数据,或组合plain数据为Java对象 以上转换都通过调用JNI接口函数来实现,也即函数原型中“JNIEnv * env”参数所指向的函数列表
3 第二个场景,C代码加载Java代码

在C程序中运行Java类,即Invocation API
两个用途实例: 1、由C语言编写,通过Invocation API执行Java类 2、Android系统Launcher加载dalvikvm
加载过程一共7步 1.生成java虚拟机选项 2.生成java虚拟机 res = JNI_CreateJavaVM(&vm, (void **)&env, &vm_args); 3.查找并加载类 cls = (*env)->FindClass(env, "InvocationApiTest"); 4.获取main()方法的ID mid = (*env)->GetStaticMethodID(env, cls, "main", "([Ljava/lang/String;)V"); 5.生成字符串对象,用作main()方法的参数 6.调用main()方法 (*env)->CallStaticVoidMethod(env, cls, mid, args); 7.销毁Java虚拟机 (*vm)->DestroyJavaVM(vm);

4 一些JNI接口细节
值得关注的有: 1、JNI函数列表里面都有什么? 大体如下三类: 类、对象、变量、方法等的引用及操作 字符串、数组操作 虚拟机接口、异常、C和Java之间函数关联 官方文档: .html
2、怎样查看方法和变量等的签名? 可以使用进行签名。不过看几个范例几乎也能猜出来。 官方文档: .html#wp16432
3、局部和全局引用 C侧可以获取Java侧实体的引用,缺省是局部应用,函数退出后即失效。一直有效的话可以使用全局引用。 显然,引用不是一个简单的指向实体的指针,不然怎么会失效呢?
5 参考文档
1、The Java Native Interface Programmer's Guide and Specification 192.9.162.55/docs/books/jni/html/jniTOC.html 2、Java Native Interface Specification .html 3、《Android框架揭秘》[韩]金泰延
前面两篇是官方的专业文档,有所有细节,但是看起来头疼且太耗时间,没有必要。《Android框架揭秘》一书对JNI做了很细致很易懂的而且足够的介绍。此书各部分都写得非常仔细,甚至略有啰嗦,各处都有自己的的整理或见解,可以看出作者写书非常的认真尽责,不是拷贝粘贴,所以在此我要大力推荐这本书。


本文发布于:2024-02-02 03:53:23,感谢您对本站的认可!

本文链接:https://www.4u4v.net/it/170681755441182.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:场景   接口   需求   JNI
留言与评论(共有 0 条评论)
   
验证码:

Copyright ©2019-2022 Comsenz Inc.Powered by ©

网站地图1 网站地图2 网站地图3 网站地图4 网站地图5 网站地图6 网站地图7 网站地图8 网站地图9 网站地图10 网站地图11 网站地图12 网站地图13 网站地图14 网站地图15 网站地图16 网站地图17 网站地图18 网站地图19 网站地图20 网站地图21 网站地图22/a> 网站地图23