4. The Invocation API

4 篇文章 0 订阅

来自:The Invocation API

1. Overview

举例说明如何使用Invocation API中的方法。下面使用C++代码创建一个Java VM,然后调用一个称为Main.test的static method。
Invocation API允许native application使用JNI interface pointer访问VM特性。

Eg:

    #include <jni.h>       /* where everything is defined */
    ...
    JavaVM *jvm;       /* denotes a Java VM */
    JNIEnv *env;       /* pointer to native method interface */
    JavaVMInitArgs vm_args; /* JDK/JRE 6 VM initialization arguments */
    JavaVMOption* options = new JavaVMOption[1];
    options[0].optionString = "-Djava.class.path=/usr/lib/java";
    vm_args.version = JNI_VERSION_1_6;
    vm_args.nOptions = 1;
    vm_args.options = options;
    vm_args.ignoreUnrecognized = false;
    /* load and initialize a Java VM, return a JNI interface
     * pointer in env */
    JNI_CreateJavaVM(&jvm, (void**)&env, &vm_args);
    delete options;
    /* invoke the Main.test method using the JNI */
    jclass cls = env->FindClass("Main");
    jmethodID mid = env->GetStaticMethodID(cls, "test", "(I)V");
    env->CallStaticVoidMethod(cls, mid, 100);
    /* We are done. */
    jvm->DestroyJavaVM();

Creating the VM

使用JNI_CreateJavaVM()方法加载和初始化一个Java VM,并且返回一个指向JNI interface pointer的指针。调用JNI_CreateJavaVM()方法的线程被认为是main thread

Attaching to the VM

The JNI interface pointer(即JNIEnv)仅仅在当前线程有效。其他线程需要访问Java VM时,它必须调用 AttachCurrentThread() 方法attach它自己到VM,然后获取一个JNI interface pointer。一旦这个线程attach到VM,native thread工作就像一个普通的运行在native method中的Java thread一样(Once attached to the VM, a native thread works just like a ordinary Java thread running inside a native method)。这个native thread会一直attached VM,直到它调用 DetachCurrentThread() 方法detach它自己为止。

Detaching from the VM

一个已经attach到VM的native thread在离开之前必须调用 DetachCurrentThread() detach它自己。如果有Java methods在调用栈中,thread不能detach它自己。

Unloading the VM

JNI_DestroyJavaVM()方法卸载Java VM。
只有current thread是唯一的non-daemon(非守护的) user thread时,VM才能真实地卸载掉。User thread包括Java thread和attached native thread。存在这个约束限制的原因是Java thread或者attached native thread 可能占用着系统资源,例如locks,windows等待。VM不能自动地释放这些资源。释放任意thread占用系统资源的操作由开发者去做。
约束限制:当VM被卸载时,当前线程是唯一正在运行的线程。

2. Library and Version Management

一旦native library被加载了,它是对所有class loaders是可见的。因此不同class loader中的两个类可能会与相同的native method关联上。这样导致两个问题:(暂不翻译)

  • A class may mistakenly link with native libraries loaded by a class with the same name in a different class loader.
  • Native methods can easily mix classes from different class loaders. This breaks the name space separation offered by class loaders, and leads to type safety problems.

解决方法是每个class loader管理它自己拥有的一系列native libraries。相同的JNI native library不能被多个class loader加载。否则会导致 UnsatisfiedLinkError。这种处理方法的好处:(暂不翻译)

  • Name space separation based on class loaders is preserved in native libraries. A native library cannot easily mix classes from different class loaders.
  • In addition, native libraries can be unloaded when their corresponding class loaders are garbage collected.

JNI_OnLoad

jint JNI_OnLoad(JavaVM *vm, void *reserved);

当native library被加载后(例如通过 System.loadLibrary),VM会调用JNI_OnLoad。JNI_OnLoad必须返回被native library需要的JNI version。
如果VM不能识别JNI_OnLoad返回的version number,VM将会卸载library,就像这个library从来没有加载过一样。

JNI_Onload_L(JavaVM *vm, void *reserved);

Library L是一个静态链接。调用System.loadLibrary(“L”)或等效的API。它返回的JNI Version必须是JNI_VERSION_1_8或之上。

JNI_OnUnload

void JNI_OnUnload(JavaVM *vm, void *reserved);

当包含native library的class loader被GC后,VM会调用JNI_OnUnload。这个方法被用来执行清理操作。

JNI_OnUnload_L(JavaVM *vm, void *reserved);

当包含静态链接的native library L的class loader被GC后,VM会调用JNI_OnUnload_L。

3. Invocation API Functions

JavaVM类型是一个指向Invocation API function table的指针。
The function table:

typedef const struct JNIInvokeInterface *JavaVM;

const struct JNIInvokeInterface ... = {
    NULL,
    NULL,
    NULL,

    DestroyJavaVM,
    AttachCurrentThread,
    DetachCurrentThread,

    GetEnv,

    AttachCurrentThreadAsDaemon
};

还有三个Invocation API functions(JNI_GetDefaultJavaVMInitArgs(),JNI_GetCreatedJavaVMs()和JNI_CreateJavaVM())不属于JavaVM function table。这三个方法可以被使用,不需要先有一个JavaVM structure。

方法介绍参考:Invocation API Functions

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值