米琪卡哇伊
要在java中调用c语言的库,需要使用Java提供了JNI。举例说明在c语言中定义一个 void sayHello()函数(打印Hello World);然后在Java中调用这个函数显示Hello Word.现在分别从Java和C语言两部分说明:1. Java 部分首先定义一个HelloNative,在其中申明sayHello函数,函数要申明为Native 类型的.如下:public class HelloNative {public native void sayHello();}编译这个类,生成class文件:javac HelloWorld.java利用javah生成需要的h文件javah HelloNative生成的 h文件大概如下:/* DO NOT EDIT THIS FILE - it is machine generated */#include /* Header for class HelloNative */#ifndef _Included_HelloNative#define _Included_HelloNative#ifdef __cplusplusextern "C" {#endif/** Class: HelloNative* Method: sayHello* Signature: ()V*/JNIEXPORT void JNICALL Java_HelloNative_sayHello(JNIEnv *, jobject);#ifdef __cplusplus}#endif#endif可以看一下上面自动生成的程序,程序include了jni.h,这个头文件在 $JAVA_HOME下的include文件夹下. 还可以发现生成的函数名是在之前的函数名前面加上了Java_HelloNative。2. C语言部分根据上面生成的h文件编写相应的代码实现,建立一个 HelloNative.cpp用来实现显示Hello World的函数.如下:#include #include "HelloNative.h"JNIEXPORT void JNICALL Java_HelloNative_sayHello(JNIEnv *, jobject){printf("Hello World!\n");}代码编写完成之后,我们再用gcc编译成库文件,命令如下;gcc -fPIC -I/usr/lib/jvm/java-7-openjdk-i386/include -I/usr/lib/jvm/java-7-openjdk-i386/include/linux -shared -o libHelloNative.so HelloNative.cpp这样就会在当前目录下生成一个libHelloNative.so的库文件.这时需要的库已经生成,在C语言下的工作已经完成了.接下来需要在Java中编写一个程序测试一下.在程序前,需要将我们的库载入进去.载入的方法是调用Java的 System.loadLibrary("HelloNative");public class TestNative{static {try {System.loadLibrary("HelloNative");}catch(UnsatisfiedLinkError e) {System.out.println( "Cannot load hello library:\n " + e.toString() );}}public static void main(String[] args) {HelloNative test = new HelloNative();test.sayHello();}}但是再编译后,运行的时候,问题又出现了.Cannot load hello library:java.lang.UnsatisfiedLinkError: no HelloNative in java.library.pathException in thread "main" java.lang.UnsatisfiedLinkError: HelloNative.sayHello()Vat HelloNative.sayHello(Native Method)at TestNative.main(TestNative.java:13)载入库失败,但是库明明就是放在当前文件夹下的,怎么会载入失败呢?用System.getProperty("java.library.path")查看,发现java.library.path中并不u存在当前的目录.主要有以下的几个解决办法:1) 将生成的库复制到java.library.path有的路径中去,当然这样不是很好2) 设置环境变量export LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH ,将当前的目录加入到LD_LIBRARY_PATH中3) 设置java 的选项,将当前的目录加入到其中 .java -Djava.library.path=. $LD_LIBRARY_PATH这样之后程序就能够成功的运行了.可以看见显示的"Hello World!"了