zoukankan      html  css  js  c++  java
  • JNI的使用总结初篇

    前言:以下内容是个人在写JNI Demo前后进行查找理解总结得出的一些结论,如有错误的地方希望路过的朋友能够指正。

    一、JNI是Java native interface的简称,目前就我所知这类方法的实现方式是由C/C++实现并保存在动态链接库里;一般是这些方法需要能更有效率的执行所以将它们定义为JNI方法(权限似乎也是一方面?),JNI方法除了加上native关键字在返回类型前面以及实现方式由C/C++实现外在使用方式上和其它方法没有区别。

    二、个人用的开发环境是Windows7x64、IDEA2017.2.1x64、VS2015x64、JDK1.8x64,此次Demo只是做了一些JNI的简单使用,真正使用场景将会涉及到如数据转换等问题。

    三、个人对JNI原理的理解:Java代码里能够调用C/C++类库是因为有JVM为这两者做适配,因为JVM本身就是C/C++写的程序,自然它能够调用C/C++写的动态链接库,故当Java代码里请求调用一个JNI方法时,会将所需数据提交给JVM,然后JVM再将参数包装后去调用dll中对应的方法,然后dll中对应方法执行完毕后再由JVM将返回数据进行一定的转换后返回给请求的Java代码处。

    四、现在就让咱们一起用用这神秘的JNI方法吧,先是定义一个类JNIDemo类:

    package silentdoer.demo;
    
    public class JNIDemo {
        static{
            System.loadLibrary("JNIMethods01");  // 这个是JNIMethods01.dll文件的前缀名
        }
    
        public static native int compare(int a, int b);
    
        public static native void hello();
    
        public native int sub(int a, int b);
    }
    // 注:后面用javah命令时如果出现编码GBK的不可映射字符错误将中文删除即可

    接着运行cmd,将路径切换到此项目的src目录,然后输入命令javah silentdoer.demo.JNIDemo按下回车键

    会在src目录下生成silentdoer_demo_JNIDemo.h头文件(也可以进入classes目录用上面的javah命令,不过这种方式如果此类里引用了其它地方的类会出现异常)

    五、接着打开VS2015,然后新建一个空解决方案起名为Demo.JNI,如图:

    然后在生成的解决方案里右键添加-新建项目,然后添加一个C++的Win32项目起名为JNIMethods01:

    点击确定然后点击下一步直到:

    选择应用程序类型Radio的DLL项点击完成(也可以取消勾选预编译头和安全开发生命周期检查);

    六、由于我的开发环境都是64位的,故要将C++生成dll的类型也改为64位,顺便将Debug改为Release,如图:

     

    将生成的头文件silentdoer_demo_JNIDemo.h复制到此项目的根目录下(不是解决方案),然后右键项目-添加-现有项

    将刚才的头文件添加到项目的头文件分类里,如图:

     此时添加的头文件里会报错,需要添加jni.h和jni_md.h两个头文件到项目的头文件分类里,这两个文件在JDK的include目录中,如图箭头:

    jni_md.h在win32子目录里;复制到项目根目录后以同样的方式添加进项目里;

    这里需要改下silentdoer_demo_JNIDemo.h中#include <jni.h>为#include "jni.h",因为"jni.h"才是从项目路径里搜索的方式。

    七、将silentdoer_demo_JNIDemo.h中的三个方法复制到JNIMethods01.cpp中并添加头文件引用,然后实现这三个方法:

     八、点击VS2015上边的生成-重新生成解决方案,然后找到此解决方案目录下的x64/Release目录,将JNIMethods01.dll复制到

    E:MyJNILib目录里(也可以在其它目录里),然后添加Path环境变量,如图:

    九、此时可以在刚才的Java项目里添加main方法:

    import silentdoer.demo.JNIDemo;
    
    public class Entrance {
        public static void main(String[] args){
            JNIDemo.hello();
            System.out.println(JNIDemo.compare(3, 4) >= 0 ? "a >= b" : "a < b");
            System.out.println(new JNIDemo().sub(10, 6));
        }
    }

    重启一遍IDEA(因为IDEA只有启动时才加载Path环境变量),运行后输出:

    hello everyone, I'm silentdoer.
    a < b
    4

    至此初篇完结,如有错误望各位指正,转载请注明原文地址。

  • 相关阅读:
    字母图形
    IBM CEO罗睿兰:科技公司屹立百年的3个秘诀
    Uva 1331
    js 推断字符串是否包括某字符串
    Verilog堵塞赋值与非堵塞赋值
    tabBar颜色改动
    零基础学python-4.2 其它内建类型
    怎样给你的Android 安装文件(APK)瘦身
    Ambari-部署常见问题
    ops
  • 原文地址:https://www.cnblogs.com/silentdoer/p/8145722.html
Copyright © 2011-2022 走看看