Java通过-jni调用c语言

  1. 首先编写一个简单的Java程序。

    public class TestJNI {

            static{

                System.loadLibrary("diaoyong");  //程序在加载时,自动加载libdiaoyong.so库

                } 

            public native void set(int value);      //声明原生函数。注意要添加native关键字

            public native int get();

            public static void main(String[] args) { 

                TestJNI test=new TestJNI(); 

                test.set(1); 

                System.out.println(test.get()); 

                     }

    }      

  2. 用javac编译TestJNI.java文件生成TestJNI.class文件

    Java通过-jni调用c语言

  3. 用javah带-jni参数编译TestJNI.class文件生成TestJNI.h文件。该文件中定义了c的函数原型。在实现c函数的时候需要。

    Java通过-jni调用c语言

  4. 生成的TestJNI.h文件如下:

    /* DO NOT EDIT THIS FILE - it is machine generated */

    #include <jni.h>

    /* Header for class TestJNI */

    #ifndef _Included_TestJNI

    #define _Included_TestJNI

    #ifdef __cplusplus

    extern "C" {

    #endif

    /*

     * Class:     TestJNI

     * Method:    set

     * Signature: (I)V

     */

    JNIEXPORT void JNICALL Java_TestJNI_set(JNIEnv *, jobject, jint);

    /*

     * Class:     TestJNI

     * Method:    get

     * Signature: ()I

     */

    JNIEXPORT jint JNICALL Java_TestJNI_get(JNIEnv *, jobject);

    #ifdef __cplusplus

    }

    #endif

    #endif

           这里JNIEXPORT和JNICALL都是JNI的关键字,表示此函数是要被JNI调用的。而jint是以JNI为中介使Java的int类型与本地的int沟通的一种类型,我们可以视而不见,就当做int使用。函数的名称是Java_再加上Java程序的package路径再加函数名组成的。参数中, 我们也只需要关心在Java程序中存在的参数,至于JNIEnv*和jclass我们一般没有必要去碰它。

  5. 编写c语言去实现这些方法,一个简单的代码如下:

            #include <stdio.h> 

            #include "TestJNI.h" 

            int i=0; 

            JNIEXPORT void JNICALL Java_TestJNI_set (JNIEnv * env, jobject obj, jint j) 

            { 

               i=j*888; 

            }   

           

           JNIEXPORT jint JNICALL Java_TestJNI_get (JNIEnv * env, jobject obj) 

            {

              printf("ok!You have successfully passed the Java call c\n");

              return i; 

            }  

  6. 生成对象文件TestJNI.o。(注意:这里面的路径/usr/lib/jvm/java/是JDk安装的路径,所以大家应根据自己的JDK路径设置。Jni_md.h和Jni.h分别在JDK的/include/linux与/include/目录下。)-Wall:打开警告开关。-fPIC:表示编译为位置独立的代码,不用此选项的话编译后的代码是位置相关的所以动态载入时是通过代码拷贝的方式来满足不同进程的需要,而不能达到真正代码段共享的目的。

    Java通过-jni调用c语言

  7. 生成动态链接库libdiaoyong.so文件,(注意:动态链接库的名字必须是 lib*.so,因为编译器查找动态连接库时有隐含的命名规则,即在给出的名字前面加上lib,后面加上.so来确定库的名称。这里是libdiaoyong.so对应于Java程序里的diaoyong) 选项 -rdynamic 用来通知链接器将所有符号添加到动态符号表中。-shared指编译后会链接成共享对象。

    Java通过-jni调用c语言

  8. 配置环境变量,我看了网上大多都是修改/home/用户目录/下的.bash_profile文件,但有的机器上没有这个文件,那么就去创建一个就行了。而我的方法直接在/home/用户目录/下的.bashrc文件(也就是我们配置环境变量的文件)进行设置。上面两种方法的设置内容是一样的,如下:

                      export LD_LIBRARY_PATH=./

    下面我就以我的方法为例做详细操作。

    先进入到/home/用户目录/下,用ls –al命令(可用于查看隐藏文件)查看.bashrc文件。

    Java通过-jni调用c语言

  9. 然后用vi编辑器或gedit编辑器打开.bashrc文件。

    Java通过-jni调用c语言

  10. 输入红线框中内容:(注意.bashrc文件里面有好多环境变量设置不要随意更动)LD_LIBRARY_PATH:这个环境变量指示动态连接器可以装载动态库的路径。

    Java通过-jni调用c语言

  11. 让.bashrc中设置立即加载

    Java通过-jni调用c语言

  12. 运行Java程序,实现去调用c语言。(注意:一定要回到Java文件所在目录运行,不然会找不到文件)。

    Java通过-jni调用c语言

猜你喜欢

转载自blog.csdn.net/sinat_32596537/article/details/86506234
今日推荐