linux下java调用C

javalinuxmakefilegccclasscommand

下面是在ubuntu 下java jni调用C语言动态链接库的具体操作步骤。
1、创建一个Java程序(TestJNI.java)定义原生的c函数。
2、用javac编译TestJNI.java生成TestJNI.class。用javah带-jni参数编译TestJNI.class生成TestJNI.h文件,该文件中 定义了c的函数原型。在实现c函数的时候需要。
3、创建Hello.c,实现TestJNI.h定义的函数。
4、编译Hello.c生成libgoodlucky.so。
5、在java虚拟机运行java程序TestJNI。

1、Test.java 源文件

 

[html] view plaincopy

 
1. public class TestJNI {  
2.   
3.     static{  
4.   
5.         System.loadLibrary("goodlucky");  
6.   
7.     }  
8.   
9.     public native void set(int value);  
10.   
11.     public native int get();  
12.   
13.     public static void main(String[] args) {  
14.   
15. td=new TestJNI();  
16.   
17.         td.set(10);  
18.   
19.         System.out.println(td.get());  
20.   
21.     }  
22.   
23. }   
 
2、javac TestJNI.java
   javah -jni Test
   生成了TestJNI.h文件
   内容如下:
 
[cpp] view plaincopy

 
1. /* DO NOT EDIT THIS FILE - it is machine generated */  
2.         #include <jni.h>  
3. /* Header for class TestJNI */  
4.           
5.         #ifndef _Included_TestJNI  
6.         #define _Included_TestJNI  
7.         #ifdef __cplusplus  
8. extern "C" {  
9.         #endif  
10. /* 
11.          * Class:     TestJNI 
12.          * Method:    set 
13.          * Signature: (I)V 
14.          */  
15. void JNICALL Java_TestJNI_set  
16.           (JNIEnv *, jobject, jint);  
17.           
18. /* 
19.          * Class:     TestJNI 
20.          * Method:    get 
21.          * Signature: ()I 
22.          */  
23.         JNIEXPORT jint JNICALL Java_TestJNI_get  
24.           (JNIEnv *, jobject);  
25.           
26.         #ifdef __cplusplus  
27.         }  
28.         #endif  
29.         #endif  
 
3、 TestJNI.c,内容如下
 
[cpp] view plaincopy

 
1. #include <stdio.h>  
2.     #include "TestJNI.h"  
3. int i=0;  
4. void JNICALL Java_TestJNI_set  
5.       (JNIEnv * env, jobject obj, jint j)  
6.     {  
7.        i=j;  
8.       
9.     }  
10.       
11.     JNIEXPORT jint JNICALL Java_TestJNI_get  
12.       (JNIEnv * env, jobject obj)  
13.     {  
14. return i;  
15.     }

 

4、

    生成:对象文件TestJNI.o (注意,运行下面命令可能会报错,主要是gcc没有安装或者安装的不是那个版本,所以重新装一次就好了,命令:yum install gcc gcc-c++ gcc-g77)

        gcc -Wall -fPIC -c TestJNI.c -I./ -I/home/abc/jdk1.7/include -I/home/abc/jdk1.7/include/linux

        生成动态库libgoodlucky.so  注意这里的goodlucky 对应TestJNI.java中goodlucky。并且这里要以lib开头命名动态库.-Wall 显示错误和警告提示   -I(不是l,就是这个害死我了,汗)后面是 jni.h,jni_md.h的路径

        gcc -Wall -rdynamic -shared -o libgoodlucky.so TestJNI.o

    

      上面的两条命令等价于下面的命令:

        gcc -Wall -fPIC  -I./ -I/usr/java/jdk1.6.0_45/include -I/usr/java/jdk1.6.0_45/include/linux -shared -o libgoodlucky.so TestJNI.c

 

       另外一种:  (g++ Base64Coder.cpp  desMethod.cpp -fPIC -shared -o desAlgorithm.so )(目前还不可用)

        export CLASSPATH=$CLASSPATP:./jna.jar 

        g++ one.cpp two.cpp three.cpp -lstdc++ -fPIC -shared -o libtest.so

        export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:${你的so目录}

export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/path/to/you/libMyLibrary_jna.so

        编译器选项-fpic和链接器选项-shared

        

 注:编译C的语句:

    gcc -fpic -c test.c   (将C编译成o文件)

    gcc -shared -o libtest.so test.o (将o文件编译成so文件)

    

        修改.bash_profile文件,配置环境变量,由于生成的.so文件在当前目录下,故

 

        .bash_profile文件设置如下

        export LD_LIBRARY_PATH=./

        或者把生成的.so文件放到/usr/lib目录下也可以。

5、java TestJNI

//JNA导入jar包

export CLASSPATH=$CLASSPATP:./jna.jar 

 

 

进阶:

1、在第四步中,编写makefile文件

  内容如下:

 

[plain] view plaincopy

 
1. libgoodlucky.so:TestJNI.o makefile  
2.     gcc -Wall -rdynamic -shared -o libgoodlucky.so TestJNI.o  
3. TestJNI.o:TestJNI.c TestJNI.h  
4.     gcc -Wall -c TestJNI.c -I./ -I/home/abc/jdk1.7/include -I/home/abc/jdk1.7/include/linux  
5. cl:  
6.     rm -rf *.o *.so




格式如下:

                一个 makefile 主要含有一系列的规则,如下:

                A: B

                (tab)<command>

                (tab)<command>

                

                每个命令行前都必须有tab符号。


思考若是java文件带有包路径呢?可以去动手做做