1 回答

TA貢獻(xiàn)1816條經(jīng)驗(yàn) 獲得超6個贊
要在java中調(diào)用c語言的庫,需要使用Java提供了JNI。
舉例說明
在c語言中定義一個 void sayHello()函數(shù)(打印Hello World);然后在Java中調(diào)用這個函數(shù)顯示Hello Word.
現(xiàn)在分別從Java和C語言兩部分說明:
1. Java 部分
首先定義一個HelloNative,在其中申明sayHello函數(shù),函數(shù)要申明為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 <jni.h>
/* Header for class HelloNative */
#ifndef _Included_HelloNative
#define _Included_HelloNative
#ifdef __cplusplus
extern "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文件夾下. 還可以發(fā)現(xiàn)生成的函數(shù)名是在之前的函數(shù)名前面加上了Java_HelloNative。
2. C語言部分
根據(jù)上面生成的h文件編寫相應(yīng)的代碼實(shí)現(xiàn),建立一個 HelloNative.cpp用來實(shí)現(xiàn)顯示Hello World的函數(shù).如下:
#include <stdio.h>
#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
這樣就會在當(dāng)前目錄下生成一個libHelloNative.so的庫文件.這時需要的庫已經(jīng)生成,在C語言下的工作已經(jīng)完成了.
接下來需要在Java中編寫一個程序測試一下.在程序前,需要將我們的庫載入進(jìn)去.載入的方法是調(diào)用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();
}
}
但是再編譯后,運(yùn)行的時候,問題又出現(xiàn)了.
Cannot load hello library:
java.lang.UnsatisfiedLinkError: no HelloNative in java.library.path
Exception in thread "main" java.lang.UnsatisfiedLinkError: HelloNative.sayHello()V
at HelloNative.sayHello(Native Method)
at TestNative.main(TestNative.java:13)
載入庫失敗,但是庫明明就是放在當(dāng)前文件夾下的,怎么會載入失敗呢?
用System.getProperty("java.library.path")查看,發(fā)現(xiàn)java.library.path中并不u存在當(dāng)前的目錄.主要有以下的幾個解決辦法:
1) 將生成的庫復(fù)制到j(luò)ava.library.path有的路徑中去,當(dāng)然這樣不是很好
2) 設(shè)置環(huán)境變量export LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH ,將當(dāng)前的目錄加入到LD_LIBRARY_PATH中
3) 設(shè)置java 的選項(xiàng),將當(dāng)前的目錄加入到其中 .java -Djava.library.path=. $LD_LIBRARY_PATH
這樣之后程序就能夠成功的運(yùn)行了.可以看見顯示的"Hello World!"了
添加回答
舉報(bào)