linuxjna呼叫so動態庫
文中提到:為什麼命名為libtest.so而不是test.so呢?因為jna在找so檔案的時候,要匹配字首為lib的so檔案
http://zhenaihua0213.blog.163.com/blog/static/50887766201129104611955/
在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的預設路徑是在ROOT下,如果你是用ROOT許可權登陸的話。
gcc -fpic -c test.c
gcc -shared -o libtest.so test.o ls看一下生成的檔案: 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 TestSo Exception in thread “main” java.lang.UnsatisfiedLinkError: Unableto load library `test`: libtest.so: cannot open shared object file:No such file or directory atcom.sun.jna.NativeLibrary.loadLibrary(NativeLibrary.java:163) atcom.sun.jna.NativeLibrary.getInstance(NativeLibrary.java:236) atcom.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) atTestSo$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這個目錄下面,一般是可以使程式執行的。
關於路徑,這個確實頭痛,在WINDOWS下還好辦,Native.loadLibrary(String,class)第一個引數用絕對路徑沒有問題,如下:
我專案位置:D:workspace est
.java檔案位置:D:workspace estscrcomsysang
CLASSPATH=.;%JAVA_HOME%libdt.jar;%JAVA_HOME%lib ools.jar;%TOMCAT_HOME%commonlibservlet-api.jar;%JAVA_HOME%jrelib
t.jar
- Java code
-
API INSTANCE
= (API)Native.loadLibrary(“D:\測試程式\DLL\API“,API.class);
相對路徑的話,如下:
放在工程的src下,釋出後出現在WEB-INFclasses下,然後在你要呼叫API INSTANCE =(API)Native.loadLibrary的類中(如類名為A),呼叫如下
String path=A.class.getResource(“/”).getPath()+”API.dll”;
//如何tomcat路徑中有空格,加上這句path=path.replaceAll(” “, ” “);
API INSTANCE = (API)Native.loadLibrary(path, API.class);
對於jna來說,如果或直接在Eclipse裡執行的話,那麼
Native.loadLibrary(“hello”,**.class)
這兒第一個引數的當前目錄就是Eclipse的目錄。
相關文章
- lua——alien庫實現lua呼叫C動態連結庫(dll、so)
- 動態庫so打包到android apkAndroidAPK
- oracle呼叫C動態庫Oracle
- 動態庫的建立和呼叫
- java動態呼叫c++庫JavaC++
- linux 動態裝載動態庫 ldd,ldconfig,ld.so.conf, ld.so.cacheLinux
- java呼叫c++動態庫之jni呼叫JavaC++
- Android native層動態載入so庫Android
- C編譯: 動態連線庫 (.so檔案)編譯
- C語言動態呼叫庫(轉)C語言
- android使用C/C++呼叫SO庫AndroidC++
- 騰訊 IVWEB 團隊:通過 ffi 在 Node.js 中呼叫動態連結庫 (.so/.dll 檔案)WebNode.js
- VS中呼叫DLL動態庫的方法
- Eclipse接入第三方動態庫.so方案Eclipse
- C#呼叫C++動態連結庫C#C++
- C++呼叫C#的動態庫dllC++C#
- 作業系統動態庫呼叫過程作業系統
- Android 開發中如何動態載入 so 庫檔案Android
- Android JNI實現Java與C/C++互相呼叫,以及so庫的生成和呼叫(JNI方式呼叫美圖秀秀so)AndroidJavaC++
- .net呼叫靜態庫
- App極限瘦身: 動態下發soAPP
- java動態呼叫webserviceJavaWeb
- VC動態呼叫DLL
- Laravel 如何實現既能靜態呼叫,又能動態呼叫Laravel
- P/Invoke之C#呼叫動態連結庫DLLC#
- golang可以呼叫C++的動態連結庫麼GolangC++
- Linux迭代呼叫共享動態庫導致segment faultLinux
- 【PB】powerbuilder呼叫VC編寫的動態連結庫UI
- 物件呼叫動態變數物件變數
- C#動態呼叫webserviceC#Web
- Linux 依賴動態庫 / 靜態庫的動態態庫 / 靜態庫Linux
- VB呼叫C程式的方法—動態連結庫法 (轉)C程式
- 靜態庫與動態庫
- linux下使用boost.python呼叫c++動態庫LinuxPythonC++
- JNI呼叫c動態連結庫函式程式碼實踐函式
- C#動態呼叫WCF介面C#
- EXECUTE IMMEDIATE 呼叫動態過程
- Android NDK祕籍--編譯靜態庫、呼叫靜態庫Android編譯