最近自己寫的一個廣告發布平台要遷移到Linux平台上,由於之前用的是windows平台的dll檔案,現在要改用.so。講下如何在Linux下面調用.so。
在linux下使用jna調用本地方法的時候,需要將C寫成的程式編譯為so檔案
1、寫一個簡單test.c檔案:
#include<stdio.h>int add(int a,int b);int add(int a,int b){ int c = a + b ; return c ;}
2、編譯為so動態連結程式庫:
gcc -fpic -c test.cgcc -shared -o libtest.so test.ols看一下產生的檔案:libtest.so test.c test.o
這樣就會產生so檔案了。 這裡為什麼要命名為libtest.so而不是test.so呢?因為jna在找so檔案的時候,要匹配首碼為lib的so檔案
3、接下來開始寫java檔案(需要下載jna.jar),我們寫一個TestSo.java:
import com.sun.jna.Library;import com.sun.jna.Native;public class TestSo {public interface LgetLib extends Library {// 調用linux下面的so檔案,注意,這裡只要寫test就可以了,不要寫libtest,也不要加尾碼LgetLib INSTANCE = (LgetLib) Native.loadLibrary("test",LgetLib.class);int add(int a,int b);}public int add(int a,int b){return LgetLib.INSTANCE.add(a,b);}public static void main(String[] args) {TestSo ts = new TestSo();int c = ts.add(10,20);System.out.println("10+20="+c);}}
4、 接下來進行編譯:
export CLASSPATH=$CLASSPATP:./jna.jar //這裡是設定環境變數javac TestSo.java
這裡直接運行TestSo的話:
java TestSoException in thread "main" java.lang.UnsatisfiedLinkError: Unable to load library 'test': libtest.so: cannot open shared object file: No such file or directoryat com.sun.jna.NativeLibrary.loadLibrary(NativeLibrary.java:163)at com.sun.jna.NativeLibrary.getInstance(NativeLibrary.java:236)at com.sun.jna.Library$Handler.<init>(Library.java:140)at com.sun.jna.Native.loadLibrary(Native.java:379)at com.sun.jna.Native.loadLibrary(Native.java:364)at TestSo$LgetLib.<clinit>(TestSo.java:7)at TestSo.add(TestSo.java:11) at TestSo.main(TestSo.java:15)
這個錯誤是指找不到so檔案。於是我們將so檔案所在的目錄設定到環境變數LD_LIBRARY_PATH中:
vim /etc/profile
在export PATH USER LOGNAME MAIL HOSTNAME HISTSIZE INPUTRC下面加入
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:${你的so目錄}
之後,你可以檢查一下設定的起沒起效果:echo $LD_LIBRARY_PATH,如果出現你設定的內容就對了,如果沒有,你可以重新開啟一個視窗再查一下
設定好環境變數之後,你就可以運行java類了:
java TestSo
10+20=30
到此運行成功。
如果你遇到了緊急的情事,而這個地方又搞不定,你可以暫時交so檔案放到/usr/lib這個目錄下面,一般是可以使程式啟動並執行。