Java 在 Linux 下调用本地方法
一、编写Java类,实现你想要实现的功能。其中本地方法要求这样声明:
private static native byte[] mytestjni();
这说明你将会使用C或者其他语言实现mytestjni(),并且返回字节数组。
//
package biz.samland;
public class TestUtils {
private static native byte[] mytestjni();
/**
* 这里是你的Java方法,间接调用mytestjni();
*/
public static byte[] getInfo(){
return mytestjni();
}
/**
* 在这里应用这个方法
*/
public static void main(String args[]){
System.out.print(byte2hex(TestUtils.getInfo()));
}
/**
* 加载静态库
*/
static {
System.load("/usr/lib/libmytestjni.so");
}
private static String byte2hex(byte[] b)
{
String hs="";
String stmp="";
for (int n=0;n
{
stmp=(java.lang.Integer.toHexString(b[n] & 0XFF));
if (stmp.length()==1) hs=hs+"0"+stmp;
else hs=hs+stmp;
if (n
}
return hs.toUpperCase();
}
}
//
二、准备编写本地方法
2.1 首先到Linux的java环境下,配置好编译环境:
export PATH=/usr/java/jdk1.5.0_06/bin:$PATH
export JAVA_HOME=/usr/java/jdk1.5.0_06
2.2 然后执行javac把写好的java文件编译成为class
javac -d . TestUtils.java
就会在当前目录下生成./biz/samland/TestUtils.class
2.3 执行javah生成头文件
javah biz.samland.TestUtils 那么就会生成./biz_samland_TestUtils.h文件。
这个文件会声明一个函数:
JNIEXPORT jbyteArray JNICALL Java_biz_samland_TestUtils_mytestjni
(JNIEnv *, jclass);
三、编写本地方法
3.1 新建一个c文件,include刚才生成的头文件,并完成本地方法的实现:
//
#include
#include "biz_samland_TestUtils.h"
JNIEXPORT jbyteArray JNICALL Java_biz_samland_TestUtils_mytestjni
(JNIEnv *env, jclass clzz) {
unsigned char testdata[16];
char path[256];
strcpy(path, "/usr/local/samland/testfile.dat");
从文件中读取数据(path, testdata);
jbyteArray theReturn = env->NewByteArray(16);
env->SetByteArrayRegion(theReturn, 0, 16, (jbyte*)testdata);
return theReturn;
}
//
3.2 编译成为静态库libmytestjni.so
g++ -Wall -c mytestjni.c -I./ -I/usr/java/jdk1.5.0_06/include -I/usr/java/jdk1.5.0_06/include/linux
g++ -Wall -rdynamic -shared -o libmytestjni.so mytestjni.o
四、测试
由于类里面写了这样一个加载方法:
System.load("/usr/lib/libmytestjni.so");
因此首先你得把刚刚生成的静态库复制到相应目录下:
cp libmytestjni.so /usr/lib/
因为 TestUtils 里面写了一个main()方法,因此你可以简单的执行 java biz.samland.TestUtils 即可看到输出效果。 不过当你真正发布这个类的时候,建议把main函数取掉.