zoukankan      html  css  js  c++  java
  • JNI 简单例子

    原文:http://www.cnblogs.com/youxilua/archive/2011/09/16/2178554.html

    1,先把c语言的编译环境搭建好,windows下这里使用mingw

    1,mingw具体配置

    配置环境变量: 
                             打开:“我的电脑->属性->高级->环境变量->系统变量”编辑如下系统变量: 
                             变量名                            变量值 
                             PATH                             C:MinGWin; 
                             LIBRARY_PATH                C:MinGWlib 
                             C_INCLUDEDE_PATH        C:MinGWinclude 
                             CPLUS_INCLUDE_PATH      C:MinGWincludec++3.4.2;C:MinGWincludec++3.4.2mingw32;C:MinGWincludec++3.4.2ackward;C:MinGWinclude

    盘符自己搞定吧…

    image 

    2,开始第一个JNI

    1,JNI的原理图

    image

    直接到官方教程那里截的….

    2,开始使用JNI

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    package kg.tom;
     
    public class MyJni {
        //使用JNI的关键字native
        //这个关键字决定我们那些方法能在我们的C文件中使用
        //只须声明,不必实现
         public native void display();
         public native double sum(double x,double y);
          
        //这个是到时候调用我们写好的C文件
        //现在用不上
        //static {
        //  System.loadLibrary("sum");
        //}
         
         
        public static void main(String[] args) {
            //到时候测试用方法现在用不上
            //new MyJni().display();
            //System.out.println(new MyJni().sum(2.0, 3.0));
        }
    }

    然后,就是返回到我们的java基础了…将我们写好的类,转换成头文件

    1,先把写好的类转换成.class文件

    image

    2,把.class文件转换成头文件,成功的话就会在src目录下看到.h文件了

     image

    打开后你会看到

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    /* DO NOT EDIT THIS FILE - it is machine generated */
    #include <jni.h>
    /* Header for class kg_tom_MyJni */
     
    #ifndef _Included_kg_tom_MyJni
    #define _Included_kg_tom_MyJni
    #ifdef __cplusplus
    extern "C" {
    #endif
    /*
     * Class:     kg_tom_MyJni
     * Method:    display
     * Signature: ()V
     */
    JNIEXPORT void JNICALL Java_kg_tom_MyJni_display
      (JNIEnv *, jobject);
     
    /*
     * Class:     kg_tom_MyJni
     * Method:    sum
     * Signature: (DD)D
     */
    JNIEXPORT jdouble JNICALL Java_kg_tom_MyJni_sum
      (JNIEnv *, jobject, jdouble, jdouble);
     
    #ifdef __cplusplus
    }
    #endif
    #endif

    native方法名称转换详解:

    英语原文 我的理解… 例子

    the prefix Java_

    转换后的native方法全部以Java_为前缀 Java_kg_tom_MyJni_display

    a mangled fully-qualified class name

    接着以类的全名标识(包名+类名) Java_kg_tom_MyJni_display
    • an underscore (“_”) separator
    以下划线为分隔符(“_”) Java_kg_tom_MyJni_display
    mangled method name 最后就是方法的名称 Java_kg_tom_MyJni_display
    • for overloaded native methods, two underscores (“__”) followed by the mangled argument signature
    这个理解不能:直译的话就是对已经读取过的native方法,用双下划线(“__”)标注 没找到

    3,就是写我们的C文件了

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    //必须的头文件jni.h
    #include <jni.h>
    //导入我们需要实现的本地方法
    #include "kg_tom_MyJni.h"
    #include <stdio.h>
     
    JNIEXPORT void JNICALL Java_kg_tom_MyJni_display
      (JNIEnv *env, jobject obj)
    {
        printf("Hello World tom!!");
        return;
    }
     
    JNIEXPORT jdouble JNICALL Java_kg_tom_MyJni_sum
      (JNIEnv *env, jobject obj, jdouble a, jdouble b)
    {
        return a + b;
    }

    4,windows下编译成dll文件,linux下编译成so文件.这里只说windows下的

    1,java基础

    找到我们的jdk文件夹,然后打开其中的include文件夹,就会看到一些头文件,看下关键的Jni.h头文件在不在,在的话,继续,不在

    自行下载一个新的jdk…

    2,把C文件编译成dll文件

    我们这里使用mingw….你会用VC6也可以用VC6编译…

    gcc -Wall -D_JNI_IMPLEMENTATION_ -Wl,--kill-at   -Id:/java/include –Id:/java/include/win32   -shared -o sum.dll java_sum_native.c

    命令 简单介绍
    -Wall -D_JNI_IMPLEMENTATION_ 把我们的C文件编译成dll
    -Wl,--kill-at   因为mingw默认是用@来进行分隔,会导致JNI机制不能读取,所以要删掉.. 
    mingw官网解释
    Id:/java/include –Id:/java/include/win32   导入我们用的的jni需要的头文件…盘符,文件夹自己修改
    -shared -o 输出配置,第一个参数为我们输出的名字(随便起),第二个参数为我们的C文件(随便起)
       

    image

    没出什么提示的话就是成功的了…

    4,运行我们的JNI

    1,用eclipse的话,我们把编译好的dll放到项目根目录,注意不是代码根目录

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    //把刚才注释的地方删掉..
    //这就是必须的,用来读取我们写好的C语言编译好的dll,后缀是系统自己辨认…千万不要自己写
    static {
            System.loadLibrary("sum");
        }
    //mian方法中
    //用底层c代码实现输出..呵呵~~
    new MyJni().display();
    //用c计算会不会快点呢..呵呵~
    System.out.println(new MyJni().sum(2.0, 3.0));

    输出结果

    image

    貌似java本身的输出,优先级比较高??

    2,补充一下:

    1,我们要运行我们编译的C文件,是与我们创建的类是必须一起存在,

    例如:我把MyJni.java删掉,然后另起一个Hello.java能不能直接调用dll中的方法呢?那是肯定不行的..因为,jni需要类名来进行查找

  • 相关阅读:
    如何使用SAP Intelligent Robotic Process Automation自动操作Excel
    OpenSAML 使用引导 IV: 安全特性
    Spring Cloud Zuul 网关使用与 OAuth2.0 认证授权服务
    微服务架构集大成者—Spring Cloud (转载)
    Spring Cloud Eureka 服务注册列表显示 IP 配置问题
    使用 Notification API 开启浏览器桌面提醒
    SignalR 中使用 MessagePack 序列化提高 WebSocket 通信性能
    配置 Nginx 的目录浏览功能
    关于 Nginx 配置 WebSocket 400 问题
    Migrate from ASP.NET Core 2.0 to 2.1
  • 原文地址:https://www.cnblogs.com/lvcha/p/3398770.html
Copyright © 2011-2022 走看看