網(wǎng)上有很多的方法添加path,大部分說的都是在~/.profile后面追加,但這只針對(duì)當(dāng)前用戶環(huán)境變量,有一種更優(yōu)雅的方法,添加全局環(huán)境變量,就是在/etc/profile.d/文件夾中新建一個(gè)*.sh,里面添加export,例如:
目前創(chuàng)新互聯(lián)已為上千的企業(yè)提供了網(wǎng)站建設(shè)、域名、網(wǎng)站空間、成都網(wǎng)站托管、企業(yè)網(wǎng)站設(shè)計(jì)、東莞網(wǎng)站維護(hù)等服務(wù),公司將堅(jiān)持客戶導(dǎo)向、應(yīng)用為本的策略,正道將秉承"和諧、參與、激情"的文化,與客戶和合作伙伴齊心協(xié)力一起成長(zhǎng),共同發(fā)展。
添加so路徑也有一種優(yōu)雅的方法,就在是/etc/ld.so.conf.d/中新建一個(gè)*.conf,并在其中添加so路徑,例如:
用JNI實(shí)現(xiàn)
實(shí)例:
創(chuàng)建HelloWorld.java
class HelloWorld
{
private native void print();
public staticvoid main(String[] args)
{
new HelloWorld().print();
}
static
{
System.loadLibrary("HelloWorld");
}
}
注意print方法的聲明,關(guān)鍵字native表明該方法是一個(gè)原生代碼實(shí)現(xiàn)的。另外注意static代碼段的System.loadLibrary調(diào)用,這段代碼表示在程序加載的時(shí)候,自動(dòng)加載libHelloWorld.so庫。
編譯HelloWorld.java
在命令行中運(yùn)行如下命令:
javac HelloWorld.java
在當(dāng)前文件夾編譯生成HelloWorld.class。
生成HelloWorld.h
在命令行中運(yùn)行如下命令:
javah -jni HelloWorld
在當(dāng)前文件夾中會(huì)生成HelloWorld.h。打開HelloWorld.h將會(huì)發(fā)現(xiàn)如下代碼:
/* DO NOT EDIT THIS FILE - it is machine generated */
#include jni.h
/* Header for class HelloWorld */
#ifndef _Included_HelloWorld
#define _Included_HelloWorld
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: HelloWorld
* Method: print
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_HelloWorld_print
(JNIEnv *, jobject);
#ifdef __cplusplus
}
#endif
#endif
該文件中包含了一個(gè)函數(shù)Java_HelloWorld_print的聲明。這里面包含兩個(gè)參數(shù),非常重要,后面講實(shí)現(xiàn)的時(shí)候會(huì)講到。
實(shí)現(xiàn)HelloWorld.c
創(chuàng)建HelloWorld.c文件輸入如下的代碼:
#include jni.h
#include stdio.h
#include "HelloWorld.h"
JNIEXPORT void JNICALL
Java_HelloWorld_print(JNIEnv *env, jobject obj)
{
printf("Hello World!\n");
}
注意必須要包含jni.h頭文件,該文件中定義了JNI用到的各種類型,宏定義等。
另外需要注意Java_HelloWorld_print的兩個(gè)參數(shù),本例比較簡(jiǎn)單,不需要用到這兩個(gè)參數(shù)。但是這兩個(gè)參數(shù)在JNI中非常重要。
env代表java虛擬機(jī)環(huán)境,Java傳過來的參數(shù)和c有很大的不同,需要調(diào)用JVM提供的接口來轉(zhuǎn)換成C類型的,就是通過調(diào)用env方法來完成轉(zhuǎn)換的。
obj代表調(diào)用的對(duì)象,相當(dāng)于c++的this。當(dāng)c函數(shù)需要改變調(diào)用對(duì)象成員變量時(shí),可以通過操作這個(gè)對(duì)象來完成。
編譯生成libHelloWorld.so
在Linux下執(zhí)行如下命令來完成編譯工作:
cc -I/usr/lib/jvm/java-6-sun/include/linux/
-I/usr/lib/jvm/java-6-sun/include/
-fPIC -shared -o libHelloWorld.so HelloWorld.c
在當(dāng)前目錄生成libHelloWorld.so。注意一定需要包含Java的include目錄(請(qǐng)根據(jù)自己系統(tǒng)環(huán)境設(shè)定),因?yàn)镠elloworld.c中包含了jni.h。
另外一個(gè)值得注意的是在HelloWorld.java中我們LoadLibrary方法加載的是
“HelloWorld”,可我們生成的Library卻是libHelloWorld。這是Linux的鏈接規(guī)定的,一個(gè)庫的必須要是:lib+庫
名+.so。鏈接的時(shí)候只需要提供庫名就可以了。
運(yùn)行Java程序HelloWorld
大功告成最后一步,驗(yàn)證前面的成果的時(shí)刻到了:
java HelloWorld
如果你這步發(fā)生問題,如果這步你收到j(luò)ava.lang.UnsatisfiedLinkError異常,可以通過如下方式指明共享庫的路徑:
java -Djava.library.path='.' HelloWorld
當(dāng)然還有其他的方式可以指明路徑請(qǐng)參考《在Linux平臺(tái)下使用JNI》。
我們可以看到久違的“Hello world!”輸出了。
新建一個(gè)sort.c文件,寫一個(gè)最簡(jiǎn)單的排序
使用 gcc -o libsort.so -fPIC -shared sort.c 產(chǎn)生libsort.so庫。
.so庫有兩種調(diào)用方法:
新建main.c文件:
使用命令 gcc -o main main.c -lsort -L. 編譯。
新建main2.c文件:
使用命令 gcc -o main2 main2.c -ldl 編譯。動(dòng)態(tài)加載.so庫的話需要-ldl。
運(yùn)行./main2后輸出遞增序列,調(diào)用成功。
-lxx
xx是你的.so文件名
其實(shí)使用方法和你使用數(shù)學(xué)庫函數(shù)是一樣的,源代碼中添加
#include math.h,編譯的時(shí)候,加上-lm參數(shù)。
注:linux下的.so文件為共享庫,相當(dāng)于windows下的dll文件。
擴(kuò)展資料:?
linux下編寫調(diào)用so文件實(shí)例
.so是Linux(Unix)下的動(dòng)態(tài)鏈接庫. 和.dll類似.
比如:
文件有: a.c, b.c, c.c
gcc -c a.c
gcc -c b.c
gcc -c c.c
gcc -shared libXXX.so a.o b.o c.o
要使用的話也很簡(jiǎn)單. 比如編譯d.c, 使用到libXXX.so中的函數(shù), libXXX.so地址是MYPATH?
gcc d.c -o d -LMYPATH -lXXX
注意不是-llibXXX
test.c文件和一個(gè)test.h,這兩個(gè)文件要生成libsotest.so文件。然后我還有一個(gè)testso.c文件,在這個(gè)文件里面調(diào)用libsotest.so中的函數(shù)。
編寫的過程中,首先是編譯so文件,我沒有編寫makefile文件,而是參考的2里面說的直接寫的gcc命令。
因?yàn)閟o文件里面沒有main函數(shù),所以是不可執(zhí)行的,所以編譯的時(shí)候要加上-c,只生成目標(biāo)文件。