zoukankan      html  css  js  c++  java
  • jni 设计的哲学

    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有几个设计的原则:
    第一、JNIEnv指针被设计成了Thread Local Storage(TLS)变量,也就是说每一个Thread, JNIEnv变量都有独立的Copy。这样做的原因主要是考虑到:
    由于JVM要运行在多个平台(除了主流的Windows,Linux等平台),JNI内部实现很多要依赖到TLS, 为了减少对TLS的依赖,所有TLS based的数据都会存放于JNIEnv中。这样相当于只依赖一个TLS based的变量JNIEnv。由于JNIEnv指针是TLS的,所以你不能把Thead#1使用的JNIEnv传给Thread#2使用。

    第二、JNIEnv中定义了一组函数指针,c/c++ Native程序是通过这些函数指针操纵Java数据。这样设计的好处是:你的c/c++ 程序不需要依赖任何函数库,或者DLL。由于JVM可能由不同的厂商实现,不同厂商有自己不同的JNI实现,如果要求这些厂商暴露约定好的一些头文件和库,这不是灵活的设计。
    而且使用函数指针表的另外一个好处是: JVM可以根据启动参数动态替换JNI实现。比如:类似于C库,JNI实现为了性能起见,并没有对调用者传入的参数进行检查。但是在调试阶段,也许这种检查是很必要的,帮助你尽早发现BUG。例如如果你使用IBM JDK,你可以指定JVM参数–Xcheck:jni,告诉JVM使用带检查的JNI实现。

    参考:
    http://java.sun.com/docs/books/jni/html/jniTOC.html

  • 相关阅读:
    godaddy 亚太机房 更换 美国机房 全过程(图)
    博客园设置访问密码
    GoDaddy Linux主机支持机房的更换
    今天电信宽代终于装上光纤了,升级或安装光纤需购光猫,可以自购。我来扫盲一下
    我来科普一下为毛很多人升级了20M的电信光纤宽带反而感觉速度更卡了
    百度浏览器使用率统计
    hdu 1281
    C#基于SMTP协议和SOCKET通信,实现邮件内容和附件的发送,并可隐藏收件人
    如何处理标注打架
    提高你的Java代码质量吧:谨慎包装类型的比较
  • 原文地址:https://www.cnblogs.com/zhangguangtao/p/3016554.html
Copyright © 2011-2022 走看看