zoukankan      html  css  js  c++  java
  • [Android] Linux下JNI简单实现过程

    大概梳理了一下JNI的过程:

    start->先写好A.java文件,里面添加native方法B,调用库C.so->编译成.class文件->用javac生成.h文件,文件包含Java_A_B的方法声明->在.c文件实现方法->.c编为C.so库文件->运行A.java->end

    下面是具体步骤。

    本文地址:http://www.cnblogs.com/rossoneri/p/4359840.html 

    首先编写一个java程序

    HelloJNI.java

    public class HelloJNI{
        public native void displayHelloJNI();//所有native关键词修饰的都是对本地的声明
        
        static{
            System.loadLibrary("MyLib");//载入本地库
        }
    
        public static void main(String[] args){
            new HelloJNI().displayHelloJNI();
        }
    }

    声明native方法:如果你想将一个方法做为一个本地方法的话,那么你就必须声明该方法为native的,并且不能实现。
    System.loadLibrary("MyLib");加载动态库
    我们可以这样理解:我们的方法 displayHelloWorld()没有实现,但是我们在下面就直接使用了,所以必须在使用之前对它进行初始化)这里一般是以static块进行加载的。同时需要注意的是System.loadLibrary();的参数“hello”是动态库的名字。

    编译写好的java文件

    javac HelloJNI.java 得到 HelloJNI.class

    生成.h头文件
    javah HelloJNI
    得到 HelloJNI.h

    /* DO NOT EDIT THIS FILE - it is machine generated */
    #include <jni.h>
    /* Header for class HelloJNI */
    
    #ifndef _Included_HelloJNI
    #define _Included_HelloJNI
    #ifdef __cplusplus
    extern "C" {
    #endif
    /*
     * Class:     HelloJNI
     * Method:    displayHelloJNI
     * Signature: ()V
     */
    JNIEXPORT void JNICALL Java_HelloJNI_displayHelloJNI
      (JNIEnv *, jobject);
    
    #ifdef __cplusplus
    }
    #endif
    #endif

    这个h文件相当于我们在java里面的接口,这里声明了一个Java_HelloWorld_displayHelloWorld (JNIEnv *, jobject);方法,然后在我们的本地方法里面实现这个方法,也就是说我们在编写C/C++程序的时候所使用的方法名必须和这里的一致


    编写本地方法

    实现和由javah命令生成的头文件里面声明的方法名相同的方法。
    test.c

    #include<stdio.h>
    #include"jni.h"
    #include"HelloJNI.h"
    
    JNIEXPORT void JNICALL Java_HelloJNI_displayHelloJNI
      (JNIEnv *env, jobject obj)
    {
        printf("this is a JNI test program!
    ");
        return;
    }

    需要将jni.h(该文件可以在%JAVA_HOME%/include文件夹下面找到)文件引入,因为在程序中的JNIEnv、 jobject等类型都是在该头文件中定义的;另外在第2行需要将HelloWorld.h头文件引入(我是这么理解的:相当于我们在编写java程序的时候,实现一个接口的话需要声明才可以,这里就是将HelloWorld.h头文件里面声明的方法加以实现。当然不一定是这样)。

    编译动态链接库

    将test.c编译成动态链接库 当前目录下

    gcc -shared -I /home/du/jdk1.7.0_71/include -I /home/du/jdk1.7.0_71/include/linux test.c -o libMyLib.so

    得到libMyLib.so动态链接库

    在HelloJNI.java中我们LoadLibrary方法加载的是“MyLib”,
    可我们生成的Library却是libMyLib。这是Linux的链接规定的,
    一个库的必须要是:lib+库名+.so。链接的时候只需要提供库名就可以了

    运行

    运行HelloJNI.java

    java HelloJNI

    Exception in thread "main" java.lang.UnsatisfiedLinkError: no MyLib in java.library.path

    java -Djava.library.path=. HelloJNI

    运行 或者

    export LD_LIBRARY_PATH=/home/du/test_code:$LD_LIBRARY_PATH
    java HelloJNI

    即可获得输出。

    参考

    Linux(Ubuntu)下JNI入门

    Linux下JNI的使用

  • 相关阅读:
    php 函数strpos()
    uploadfy api中文文档
    thinkphp + 美图秀秀api 实现图片裁切上传,带数据库
    mysql 操作用户权限
    window.location 小结)
    turn.js 图书翻页效果
    thinkphp 内置标签volist 控制换行
    js 数据类型转换
    quartz 2.2.1
    Mysql测试链接
  • 原文地址:https://www.cnblogs.com/rossoneri/p/4359840.html
Copyright © 2011-2022 走看看