zoukankan      html  css  js  c++  java
  • JNI的一个简单实例

    本例子使用的操作系统MacOS, 64位JVM。

    JNI编写的几个步骤如下:

    编写Java代码,并注明native方法:

    public class HelloJni {
    
        public native void displayHelloJni();
    
        public static void main(String[] args) {
            HelloJni helloJni = new HelloJni();
            helloJni.displayHelloJni();
        }
    
        static {
            System.loadLibrary("HelloJniImpl");
        }
    }

    其中声明displayHelloJni()方法为本地方法,在static静态块中用System.loadLibrary()加载本地库。

    使用javac命令编译此java类:

    javac com/xxx/clamaa/jni/HelloJni.java 

      

    利用javah命令生成C语言的头文件(.h文件)

    javah com.xxx.clamaa.jni.HelloJni

    执行完成后,就在执行路径下生成名称为com_xxx_clamaa_jni_HelloJni.h的头文件:

    #include <jni.h>
    /* Header for class com_xxx_clamaa_jni_HelloJni */
    
    #ifndef _Included_com_xxx_clamaa_jni_HelloJni
    #define _Included_com_xxx_clamaa_jni_HelloJni
    #ifdef __cplusplus
    extern "C" {
    #endif
    /*
     * Class:     com_yonyou_clamaa_jni_HelloJni
     * Method:    displayHelloJni
     * Signature: ()V
     */
    JNIEXPORT void JNICALL Java_com_xxx_clamaa_jni_HelloJni_displayHelloJni
      (JNIEnv *, jobject);
    
    #ifdef __cplusplus
    }
    #endif
    #endif
    

    然后在同级的目录下新建一个HelloJniImpl.cpp文件,这个与HelloJni.java中定义的System.loadLibrary()的文件名一致。

    #include "com_xxx_clamaa_jni_HelloJni.h"
    #include <iostream>
    #include <jni.h>
    using namespace std;
    /*
     * Class:     HelloWorld
     * Method:    displayHelloWorld
     * Signature: ()V
     */
    JNIEXPORT void JNICALL Java_com_xxx_clamaa_jni_HelloJni_displayHelloJni
      (JNIEnv *, jobject)
     {
        cout << "Hello Jni by clamaa!";
        return;
    }

    编译C++代码的时候在MacOS下和在Linux Windows有所不同, 不是编译成.so或者dll, 而是MacOS自己的jnilib. 并且jni.h的目录也比较特殊, 是/System/Library/Frameworks/JavaVM.framework/Headers/,执行的命令g++,

    g++ -dynamiclib -o libhellojniimpl.jnilib HelloJniImpl.cpp -framework JavaVM -I/System/Library/Frameworks/JavaVM.framework/Headers

    编译完成后,就生成libhellojniimpl.jnilib文件,此时执行结果为:

    java com.xxx.clamaa.jni.HelloJni
    >Hello Jni by clamaa!

    生成的文件名称必须为: libhellojniimpl.jnilib,否则抛出异常:

    Exception in thread "main" java.lang.UnsatisfiedLinkError: no HelloJniImpl in java.library.path
    	at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1857)
    	at java.lang.Runtime.loadLibrary0(Runtime.java:870)
    	at java.lang.System.loadLibrary(System.java:1119)
    	at com.yonyou.clamaa.jni.HelloJni.<clinit>(HelloJni.java:16)

    如果设置成带参数的本地方法,那么生成的参数会多一个jstring

    Java_HelloWorld_print(JNIEnv *env, jobject obj, jstring str)

    与原来的实现方式,调用方式都一样,这样简单的JNI实现就完成了。 

     如果我们在原来的cpp实现中加入一行抛出异常的代码:

    cout << "Hello Jni by clamaa!";
    throw 1;
    return;

    那么在执行的过程中也会抛出对应的错误:

    java com.yonyou.clamaa.jni.HelloJni
    >libc++abi.dylib: terminating with uncaught exception of type int
    >Hello Jni by clamaa!Abort trap: 6
  • 相关阅读:
    Java正则表达式入门
    sql join
    java collection
    JAVA中this用法小结
    SQL Server 触发器
    SQL 存储过程
    123456 所有组合 递归
    sublime plugin & add number to mulitple line .
    重做树莓派系统盘
    制作树莓派系统盘
  • 原文地址:https://www.cnblogs.com/mmaa/p/5789917.html
Copyright © 2011-2022 走看看