1. 安卓/linux中怎樣調用原有的JNI so庫函數
電腦上的CPU為 x86,手機CPU為ARM架構,你的動態鏈接庫必須要ARM版Gcc編譯器編譯後才能跑在手機上,android NDK裡面附帶了一個ARM版的編譯器,你用NDK的編譯器重新編譯,然後就可以用JNI調用了,JNI調用不是一言兩語能說清的,有專門的教程,如果嫌麻煩,那就別用C寫。如果是做簡單的應用,幹嘛還要用C語言寫,JDK可以滿足絕大部分要求,要是嫌麻煩那就還是少碰NDK。
2. 如何在linux下調用.so庫裡面的類成員函數
直接上代碼
[User:root Time:16:46:48 Path:/home/liangdong/cpp]$ ll
total 12
-rw-r--r--. 1 root root 120 May 4 16:46 libtest.cpp
-rw-r--r--. 1 root root 85 May 4 16:45 libtest.h
-rw-r--r--. 1 liangdong daemon 141 May 4 16:42 main.cpp
[User:root Time:16:46:48 Path:/home/liangdong/cpp]$ cat libtest.cpp libtest.h main.cpp
#include "libtest.h"
#include <iostream>
using namespace std;
void test::function() {
cout<<"test::function"<<endl;
}
#ifndef _H_TEST
#define _H_TEST
class test {
public:
void function();
};
#endif
#include <iostream>
#include "libtest.h"
using namespace std;
int main(int argc, char* const argv[]) {
test t;
t.function();
return 0;
}
[User:root Time:16:46:55 Path:/home/liangdong/cpp]$ g++ -o libtest.so -fPIC -shared libtest.cpp -I.
[User:root Time:16:47:29 Path:/home/liangdong/cpp]$ g++ -o main main.cpp -L. -ltest
[User:root Time:16:47:48 Path:/home/liangdong/cpp]$ ll
total 28
-rw-r--r--. 1 root root 120 May 4 16:46 libtest.cpp
-rw-r--r--. 1 root root 85 May 4 16:45 libtest.h
-rwxr-xr-x. 1 root root 5773 May 4 16:47 libtest.so
-rwxr-xr-x. 1 root root 5876 May 4 16:47 main
-rw-r--r--. 1 liangdong daemon 141 May 4 16:42 main.cpp
[User:root Time:16:47:50 Path:/home/liangdong/cpp]$ ./main
./main: error while loading shared libraries: libtest.so: cannot open shared object file: No such file or directory
[User:root Time:16:47:51 Path:/home/liangdong/cpp]$ export LD_LIBRARY_PATH=.
[User:root Time:16:48:01 Path:/home/liangdong/cpp]$ ./main
test::function
[User:root Time:16:48:04 Path:/home/liangdong/cpp]$
3. linux環境java如何調用so文件
用JNI實現
實例:
創建HelloWorld.java
class HelloWorld
{
private native void print();
public staticvoid main(String[] args)
{
new HelloWorld().print();
}
static
{
System.loadLibrary("HelloWorld");
}
}
注意print方法的聲明,關鍵字native表明該方法是一個原生代碼實現的。另外注意static代碼段的System.loadLibrary調用,這段代碼表示在程序載入的時候,自動載入libHelloWorld.so庫。
編譯HelloWorld.java
在命令行中運行如下命令:
javac HelloWorld.java
在當前文件夾編譯生成HelloWorld.class。
生成HelloWorld.h
在命令行中運行如下命令:
javah -jni HelloWorld
在當前文件夾中會生成HelloWorld.h。打開HelloWorld.h將會發現如下代碼:
/* 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
該文件中包含了一個函數Java_HelloWorld_print的聲明。這裡麵包含兩個參數,非常重要,後面講實現的時候會講到。
實現HelloWorld.c
創建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的兩個參數,本例比較簡單,不需要用到這兩個參數。但是這兩個參數在JNI中非常重要。
env代表java虛擬機環境,Java傳過來的參數和c有很大的不同,需要調用JVM提供的介面來轉換成C類型的,就是通過調用env方法來完成轉換的。
obj代表調用的對象,相當於c++的this。當c函數需要改變調用對象成員變數時,可以通過操作這個對象來完成。
編譯生成libHelloWorld.so
在Linux下執行如下命令來完成編譯工作:
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
在當前目錄生成libHelloWorld.so。注意一定需要包含Java的include目錄(請根據自己系統環境設定),因為Helloworld.c中包含了jni.h。
另外一個值得注意的是在HelloWorld.java中我們LoadLibrary方法載入的是
「HelloWorld」,可我們生成的Library卻是libHelloWorld。這是Linux的鏈接規定的,一個庫的必須要是:lib+庫
名+.so。鏈接的時候只需要提供庫名就可以了。
運行Java程序HelloWorld
大功告成最後一步,驗證前面的成果的時刻到了:
java HelloWorld
如果你這步發生問題,如果這步你收到java.lang.UnsatisfiedLinkError異常,可以通過如下方式指明共享庫的路徑:
java -Djava.library.path='.' HelloWorld
當然還有其他的方式可以指明路徑請參考《在Linux平台下使用JNI》。
我們可以看到久違的「Hello world!」輸出了。
4. BEAN調用本地的庫(LINUX下的SO文件)不成功的幾種可能情況
一是安全性,調用的SO文件中調用了系統頂級環境,即對於JAVA來說是RUNTIME環境,則用JSP調用BEAN不能成功.
三是路徑問題,SO文件是否用了絕對路徑或在CLASSPATH中,如果作為APPLICATION調用SO,應該用紅對路徑或在系統的CLASSPATH中,但作為BEAN調用應該放在SERVLET的引擎的根目錄下或SERVLET的CLASSPATH中,即/WEB-INF/classes這樣的目錄而不是系統的CLA
5. 基於Debian的linux上如何調用dll動態鏈接庫,或者.so文件
用交叉編譯環境是可以的。
如mingw。
建議在Windows下安裝mingw,然後調試。直接調用是肯定不行的。
參考我的博客:
有個 mono你可以試試,或者是利用wine來讀取,不過不管怎麼樣都不能直接讀取,但是間接的是可以的。大概的就這兩種方法,你可以去wine和mono的網站看看。
應該有不少這方面的資料的
6. linux的C編程,怎麼使用so文件
linux下的.so文件為共享庫,相當於windows下的dll文件,使用方法如下:
在你的工程源代碼里包含.h頭文件,然後可以調用動態庫里的函數,在鏈接的時候加上如下編譯器參數:
-l xx.so
如果你的so文件是以lib開頭的,還可以直接這樣使用:
-lxx
xx是你的.so文件名
其實使用方法和你使用數學庫函數是一樣的,源代碼中添加
#include <math.h>,編譯的時候,加上-lm參數。
7. linux上.so文件可以直接運行嗎
so文件不可以直接運行的,so文件是動態函數庫文件,函數庫文件(包括.a文件和.so文件)只能用來被調用運行,不能直接運行的,so文件就相當於Windows下的dll文件,dll文件就是不能直接運行的。
8. LINUX下.so結尾的文件如何運行,或者使用
.so結尾的文件是動態鏈接庫,動態鏈接庫不能主動運行,只能被動調用。
.so的使用方法:
需要這個庫放置到程序的搜索路徑下
需要這個庫提供的頭文件在c/c++程序中鏈接調用
c/c++程序執行時會到搜索路徑下動態載入.so庫
9. 請教關於android linux動態庫.so的載入調用
1.在使用第三方的.so庫做android開發,發現僅僅放到AndroidProject/libs/armeabi/libminivenus.so這個位置,使用System.loadLibrary載入起來可以正常使用。
2.庫的名字必須是libminivenus.so,不可以改名字。也不可以使用System.load從其他地方載入(非SD卡)。如果將庫的名字或者載入位置改動,調用的jni介面就返回錯誤。
3.libminivenus.so中確實有libminivenus的欄位,將庫的名字與該欄位一起修改結果無效。