java調用so
① java 調用so文件
在命令行中運行如下命令:
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!」輸出了。
② java調用.so動態庫,除了JNI方法以外,有其他的辦法嗎沒有C的源碼,只有so。
沒有見過其他的方法,另外,JNI也不需要有C的源代碼。
③ 關於Android開發中Java對於.so庫的調用
android掉用c的so包就是通過jni
,
應該給你的jar包就是用來調用so包的
。不會讓你直接掉so包的放心。so包一般都是為了保證核心代碼不被反編譯
,另外就是效率高才會用,或者就是開發游戲
。
他們說夠用應該是jar包已經和so包的jni調用介面都調好了
,
你用jar包就行了
④ Xamarin 怎麼調用java的 so文件
1 、編寫java代碼
package net.lu;
public class HelloJNI {
static {
System.loadLibrary("HelloJNI");
}
public native static int get();
public native static void set(int i);
public static void main(String[] args) {
HelloJNI test = new HelloJNI();
test.set(10);
System.out.println(test.get());
}
}
2、在HelloJNI.java文件所在目錄下編譯.java文件。
javac HelloJNI.java
3、生成.h頭文件,需要注意的是,要在src目錄層生成文件
... src] # javah -jni net.lu.HelloJNI
4、編寫.c 文件
#include "net_wangliping_HelloJNI.h"
int i = 0;
JNIEXPORT jint JNICALL Java_net_wangliping_HelloJNI_get(JNIEnv *env, jclass jc)
{
return i;
}
JNIEXPORT void JNICALL Java_net_wangliping_HelloJNI_set(JNIEnv *env, jclass jc, jint j)
{
i = 2*j;
}
5、生成.so文件
[root@turbolinux src]# gcc -I/usr/java/jdk1.5.0_13/include/linux -I/usr/java/jdk1.5.0_13/include -fPIC -shared -o libHelloJNI.so HelloJNI.c
6、eclipse 調用SO文件
最簡單的方式,調用 System.out.println(System.getProperty("java.library.path"));
得到/usr/java/jdk1.5.0_13/jre/lib/i386,將SO文件放在該目錄下
運行java程序,輸出了由C語言函數計算出的結果
⑤ 以arm編譯的so庫怎麼在java中調用
:用JNI實現 實例: 創建HelloWorld.java class HelloWorld { private native void print(); public staticvoid main(String[] args) { new HelloWorld().print(); } static { System.loadLibrary("HelloWorld"); } } 注意print方法的聲明,
⑥ 什麼是SO文件
so文件是Linux下的程序函數庫,即編譯好的可以供其他程序使用的代碼和數據。