下面是在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。
格式如下:
一个 makefile 主要含有一系列的规则,如下:
A: B
(tab)<command>
(tab)<command>
每个命令行前都必须有tab符号。
具体可参考:http://goodcandle.cnblogs.com/archive/2006/03/30/278702.html
参考见:
http://watershitter.iteye.com/blog/477615#comments
http://lwjlaser.iteye.com/blog/779270
http://blog.csdn.net/kangkanglou/article/details/5807787
思考若是java文件带有包路径呢?可以去动手做做
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 源文件
- public class TestJNI {
- static{
- System.loadLibrary("goodlucky");
- }
- public native void set(int value);
- public native int get();
- public static void main(String[] args) {
- TestJNI td=new TestJNI();
- td.set(10);
- System.out.println(td.get());
- }
- }
2、javac TestJNI.java
javah -jni Test
生成了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
3、 TestJNI.c,内容如下
- #include <stdio.h>
- #include "TestJNI.h"
- int i=0;
- JNIEXPORT void JNICALL Java_TestJNI_set
- (JNIEnv * env, jobject obj, jint j)
- {
- i=j;
- }
- JNIEXPORT jint JNICALL Java_TestJNI_get
- (JNIEnv * env, jobject obj)
- {
- return i;
- }
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文件
内容如下:
- libgoodlucky.so:TestJNI.o makefile
- gcc -Wall -rdynamic -shared -o libgoodlucky.so TestJNI.o
- TestJNI.o:TestJNI.c TestJNI.h
- gcc -Wall -c TestJNI.c -I./ -I/home/abc/jdk1.7/include -I/home/abc/jdk1.7/include/linux
- cl:
- rm -rf *.o *.so
格式如下:
一个 makefile 主要含有一系列的规则,如下:
A: B
(tab)<command>
(tab)<command>
每个命令行前都必须有tab符号。
具体可参考:http://goodcandle.cnblogs.com/archive/2006/03/30/278702.html
参考见:
http://watershitter.iteye.com/blog/477615#comments
http://lwjlaser.iteye.com/blog/779270
http://blog.csdn.net/kangkanglou/article/details/5807787
思考若是java文件带有包路径呢?可以去动手做做