JNI - 设计概述

2 篇文章 0 订阅

前言

本文是Oracle官方JNI文档的翻译基础上加上部分个人理解,原文地址 Chapter 2:Design Overview

本文介绍 JNI(Java Native Interface)的主要设计问题,这些问题很多跟Native方法相关,调用方法的介绍在JNI - 接口调用
JNI最大的好处在于对底层JVM实现没有强制约束,所以JVM供应商可以在不影响其他JVM功能的基础上支持JNI。开发者可以开发一份Native应用或库,然后运行在所有支持JNI的JVM上。

JNI 接口函数及指针

Native代码通过JNI函数调用JVM的功能,JNI函数作为接口指针使用。接口指针是指针的指针,接口指针指向一组指针,其中每个指针指向一个接口函数,每个接口函数在指针数组中都有预定义的偏移。下图介绍接口函数指针的组织形式。

JNI接口以类似C++虚函数表和COM接口的形式组织。使用接口表而不使用硬连接条目的好处在于分离JNI命名空间及Native代码,VM可以提供几个版本的JNI函数表。比如VM可以提供两个JNI函数表:

  • 一个用于非法参数检查,适用于调试
  • 另一个执行最小的JNI规范检查,从而获取更高的效率

JNI接口指针只在当前线程有效,所以不能将JNI接口指针进行跨线程传递。VM的实现可能在JNI接口指针指向区域存放线程独立数据(thread-local data)。

Native方法以参数形式获取JNI接口指针,VM保证在同一线程中多次调用Native方法都会获得同一个JNI接口指针。但Native方法可能在不同的Java线程调用,所以Native方法可能会接收到不同的JNI接口指针。

编译、加载、链接Native方法

因为JVM是多线程的,Native库也应该使用多线程环境编译和链接。比如Sun Studio编译器编译C++代码应该使用 -mt 标志, 使用GNU gcc编译器应该使用 -D_REENTRANT 或 -D_POSIX_C_SOURCE。

Native方法通过 System.loadLibrary 方法加载。下述示例中,类初始化方法加载一个包含f方法的特定平台Native库:

package pkg; 

class Cls {
    native double f(int i, String s);
    static {
        System.loadLibrary(“pkg_Cls”);
    }
}

传入System.loadLibrary方法的参数是开发者决定的Native库名称,传入参数会根据规矩生成平台特定的Native库名称。比如Solaris系统将pkg_Cls转化为libpkg_Cls.so,但在win32平台下会将pkg_Cls转化为pkg_Cls.dll。

开发者可使用一个Native库来存储任意数量类所需的Native方法,只需要这些类都是通过相同的类加载器加载。VM内部为每个类加载器维护了一个已加载Native库的列表。供应商应该选择Native库名称以尽可能减少命名冲突。

一个Native库可能被静态链接到VM,组合Native库和VM镜像的方法取决于具体的JVM实现。Native库只有在System.loadLibrary或同等API返回成功之后才被认为已加载。

当且仅当在Native库L暴露出一个名为 JNI_OnLoad_L 的函数时,Native库L才被视为和VM镜像静态链接。静态链接Native库同时暴露 JNI_OnLoad_L 和 JNI_OnLoad 函数时JNI_OnLoad 将被忽略,同时暴露 JNI_OnUnLoad_L 和 JNI_OnUnLoad 函数时JNI_OnUnLoad 将被忽略。

当静态Native库L第一次被System.loadLibrary(“L”)或同等API调用时,JNI_OnLoad_L将会使用跟JNI_OnLoad一致的参数及返回值被调用。若Native库已被静态链接,那么名称相同的动态库将无法链接。

开发者可以使用JNI函数 RegisterNatives() 注册native方法与类之间的关联,这在静态链接中非常实用。

解析Native方法

// todo

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值