日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

java JNI调用C语言动态链接库(java.lang.UnsatisfiedLinkError: no yourClassName in java.library.path 异常的解决方法)

發布時間:2023/12/3 编程问答 16 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java JNI调用C语言动态链接库(java.lang.UnsatisfiedLinkError: no yourClassName in java.library.path 异常的解决方法) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
轉自:?http://watershitter.iteye.com/blog/477615
今天花了至少3個小時跑這個java調c的動態鏈接庫的Hello,native world的程序。?
把所有犯的錯誤和要點總結一下!?
1 java 中 c語言函數的聲明?
??? public native static void greeting(); //就像是接口聲明一樣,不過有native!?
2 編譯 javac HelloNative.java ,然后使用 javah?
??????javah HelloNative會自動產生c的頭文件HelloNative.h3 生成的頭文件 的 第一句子為?
? #include <jni.h>?
? 但是gcc里面默認環境可不知道jni.h是什么東西,jni.h在jdk的$JAVA_HOME/include或者$JAVA_HOME/include/linux下面,可進去查看一下~?

4 接下來就是根據HelloNative.h中聲明的方法寫C語言的實現,注意,自動生成的那個函數名字很長,并且 開頭的? Java是大寫的,大小寫很致命,(最后我的程序在動態庫已經加載好的情況下報錯:java.lang.UnsatisfiedLinkError: HelloNative.greeting()V,就是因為c語言中的函數名字大小寫寫錯,奇怪!編譯不報錯.....)?

5 linux下編譯生成動態庫,注意不同環境的不一樣~?
??gcc -fPIC -I jdk/include -I jdk/include/linux -shared -o libHelloNative.so HelloNative.c?
? 在這里,我犯的錯:a,不理解 -I jdk -I 是include,顯示指定庫的庫的地址,自然后面的jdk是要用你的設計地址替換的,b, 著急的去網上搜索問題,沒有注意的在linux下,動態鏈接庫的名字 必須是 lib****.so,必須以lib開頭!?

6 編譯生成了 libHelloNative.h之后,接下寫一個test類,如 HelloNativeTest,?
當然要調用System.loadLibrary("HelloNative");注意此時不要lib,也不要.so!;?
調用執行 HelloNative.greeting();這個時候錯誤又來了:?
java.lang.UnsatisfiedLinkError: no HelloNative in java.library.path。這個錯誤很經典,原因:是java找不到庫路徑~:?
顯然: libHelloNative.so放在當前路徑 ".",只linux執行的時候卻不知道在當前路徑找。 linux很“傻”很“復雜”~?
(java.lang.UnsatisfiedLinkError: no yourClassName in java.library.path的解決方法,推薦 2nd solution)
1)?linux下面java.library.path 和環境變臉 jdk/bin的那個個PATH不是一回事情,有另外一個默認變量 LD_LIBRARY_PATH來保存他的信息。而windows下,首先java會找當前目錄,其次,它會去環境變量的地址找!
2)?由于linux的路徑特殊,所以,解決方法 1-可以調用sysout(System.getProperty("java.library.path"));來查看! 然后把 libXXXX.so拷貝到那里面的目錄下去?
3) 設置環境變量 export LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH , 但是設置到哪里呢? /etc/profile ? or /root/.bashrc 不知道...忘記了linux的加載順序了~?
4) 可以單次執行時候指定library位置:?? java -Djava.library.path=. HelloNativeTest?

總結犯錯:1不知道gcc編譯時候指定庫 2 不了解java.libray.path的特點,特別是砸linux下 3 c語言實現函數的時候拼寫錯誤 4 排除問題不夠理性,系統化,出現了煩躁情緒,導致效率低。 時刻明白,機器只是做你指定的事情,總是你自己出錯了~~~?

附:gcc 參數解釋(轉載):?
?? 最主要的是GCC命令行的一個選項:?
-shared 該選項指定生成動態連接庫(讓連接器生成T類型的導出符號表,有時候也生成弱連接W類型的導出符號),不用該標志外部程序無法連接。相當于一個可執行文件?

l -fPIC:表示編譯為位置獨立的代碼,不用此選項的話編譯后的代碼是位置相關的所以動態載入時是通過代碼拷貝的方式來滿足不同進程的需要,而不能達到真正代碼段共享的目的。?

l -L.:表示要連接的庫在當前目錄中?

l -ltest:編譯器查找動態連接庫時有隱含的命名規則,即在給出的名字前面加上lib,后面加上.so來確定庫的名稱?

l LD_LIBRARY_PATH:這個環境變量指示動態連接器可以裝載動態庫的路徑。?

l 當然如果有root權限的話,可以修改/etc/ld.so.conf文件,然后調用 /sbin/ldconfig來達到同樣的目的,不過如果沒有root權限,那么只能采用輸出LD_LIBRARY_PATH的方法了。?
4、注意?

調用動態庫的時候有幾個問題會經常碰到,有時,明明已經將庫的頭文件所在目錄 通過 “-I” include進來了,庫所在文件通過 “-L”參數引導,并指定了“-l”的庫名,但通過ldd命令察看時,就是死活找不到你指定鏈接的so文件,這時你要作的就是通過修改LD_LIBRARY_PATH或者/etc/ld.so.conf文件來指定動態庫的目錄。通常這樣做就可以解決庫無法鏈接的問題了。?

總結

以上是生活随笔為你收集整理的java JNI调用C语言动态链接库(java.lang.UnsatisfiedLinkError: no yourClassName in java.library.path 异常的解决方法)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。