已经半年没有更新博客了,今天终于找到了可以写的东西,虽然这种东西写过的大神已经很多了,我只是新瓶装旧酒而已。写点自己的感悟和大家分享,也帮助自己加深记忆。
OK~言归正传,相信很多童鞋肯定和我一样喜欢用c++处理一些算法问题,但是有时候应用是java写的,这个时候就非常希望能够在java代码里调用c++的模块了。感谢JNI的存在~
下面,就介绍JNI的使用,以及关于c/c++动态链接库的编译问题了。
首先,先编写一个java文件,这个文件作为调用c/c++的载体吧,例子:
public class Test{
public native void hello();
public static void main(String[] args){
System.loadLibrary("Test");
Test tt = new Test();
tt.hello();
}
}
在这分代码里,hello方法就是之后需要用c/c++实现的方法,然后想调用只要new一个Test类就好了。
System.loadLibrary("Test")这一行表示加载Test这个动态链接库(在linux(unix)里对应的文件就是libTest.so,如果字符串是XXX,那么文件就是libXXX.so,这个字符串很随意,不一定要和java文件的类名一致)
然后就是编译该代码了:javac Test.java
再之后,还得生成相应动态链接库的头文件:javah Test,输入完这个命令之后,当前目录下就会多出Test.h这个文件,内容如下:
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class Test */
#ifndef _Included_Test
#define _Included_Test
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: Test
* Method: hello
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_Test_hello
(JNIEnv *, jobject);
#ifdef __cplusplus
}
#endif
#endif
乱七八糟的一大堆,不用管,只要看清楚这里定义的函数就好了:
JNIEXPORT void JNICALL Java_Test_hello
(JNIEnv *, jobject);
这个函数相当于就是Test类里的那个hello函数,将其用c/c++实现,Test类调用hello函数时调用的就是这些c/c++代码
所以,接下来就编写一个Test.c(cpp)文件,实现这个方法
#include "Test.h"
#include <cstdio>
JNIEXPORT void JNICALL Java_Test_hello
(JNIEnv *, jobject){
printf("Hello World\n");
}
OK了。下面就要编译这个c/c++文件了,它的目标文件就是***.so(linux下的c/c++动态链接库,so是 shared object的缩写,共享库)
linux将c/c++源文件编译为.so文件的基本命令为
gcc -shared -fPIC -o ***.so ***.c
或 g++ -shared -fPIC -o ***.so ***.cpp
但是,因为这里有个特殊的头文件jni.h 所以直接这么弄肯定没法编译过(除非jni.h所在路径已经在环境变量里了),因此我们在编译的时候必须再增加参数,那就是关于jni需要用到的头文件所在的目录
linux下找到jni.h的方法是找到jdk的安装路径,/usr/lib/jvm 这个路径下就会有你安装的jdk,我装的是openjdk6,所以我的全部路径就是 /usr/lib/jvm/java-6-openjdk/include 以及/usr/lib/jvm/java-6-openjdk/include/linux
所以我的编译命令就是g++ -shared -fPIC -I/usr/lib/jvm/java-6-openjdk/include -I/usr/lib/jvm/java-6-openjdk/include/linux -o Test.so Test.cpp
这样就能得到Test.so 这个共享库了,然后用 java Test 运行即可
这个时候可能会出错,因为Test在加载动态链接库的时候不知到它的路径,环境变量里有一个 LD_LIBRARY_PATH 只要将其复制为动态链接库所在路径即可(当然这么做的结果就是只能在当前shell中有效)
export LD_LIBRARY_PATH = 动态链接库所在路径
java Test
屏幕上就会输出 hello了
…………………………………………………………
以上就是jni一个最简单的例子,能够用java调用c/c++代码了