javaso調用
『壹』 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語言函數計算出的結果
『貳』 關於Android開發中Java對於.so庫的調用
android掉用c的so包就是通過jni
,
應該給你的jar包就是用來調用so包的
。不會讓你直接掉so包的放心。so包一般都是為了保證核心代碼不被反編譯
,另外就是效率高才會用,或者就是開發游戲
。
他們說夠用應該是jar包已經和so包的jni調用介面都調好了
,
你用jar包就行了
『叄』 當java調用c語言編寫的so動態庫時,缺少參數時為什麼還能調用且不提示錯誤
那你在C 中這個sub方法裡面,把第二個參數打出來看看,是不是空
『肆』 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 通過jna調用so文件,導出函數返回類型為介面類的要怎麼調用
這個在網上有很多例子的。 char* outputData 參數對應 java中的應該是jstring或是jbyte[],本地代碼中在返回前,生成java類型數據賦值給這個參數才可以。
『陸』 關於Android開發中Java對於.so庫的調用
廠家並沒有欺騙你或者是含糊你的意思,確實是只提供給你jar包以及 so 庫就可以了,做法是這樣子的:
1.比如我現在在用net.sqlcipher.database 這個加密庫(網上能搜得到的,用於資料庫加密)。 那麼我現在就在項目用載入這個jar包(在你的項目單擊右鍵-》屬性-》Java Build Path-》Libraries-》Add Jars,選擇提供給你的jar包,我這里是 sqlcipher.jar,然後在Order and Export勾選你剛剛載入的 jar包。)
2.打開你的workspace目錄,在你的項目目錄下創建一個文件夾libs(如果文件夾不存在的話),然後將提供給你的so庫放入該目錄,基本架構就算是搭建好了。
3.進行開發,這里你需要問一下提供給你jar包的廠家,基本的用法,否則的話是無法進行開發的,因為你都不知道怎麼去用。 sqlcipher的基本用法是:
SQLiteDatabase.loadLibs(this); //載入 so庫文件,你的廠家的方法應該也是類似。
File databaseFile = getDatabasePath(SQLite_toll.DATABASE_NAME);
databaseFile.mkdirs();
databaseFile.delete();
SQLiteDatabase database = SQLiteDatabase.openOrCreateDatabase(databaseFile, helper_SharedPreferences.get_str_sp("database_cipher",this), null);
SQLite_toll initToll = new SQLite_toll(this, avaSys);
initToll.onCreate(database);
database.close();
//因為我sqlcipher是用於資料庫加密的,所以你所看到的都是資料庫的一些方法,你廠家提供給你的jar包的用法,你是要去問他們的,或者他們的是否有開源代碼,又或者是網上也有很多人使用,那麼能搜到相關資料。
根據你補充的提問,那麼就是System.loadLibrary(this); ,就可以調用了
『柒』 java對so庫和jar哪個調用快,裡面封裝類似功能的話
1、編寫java代碼
packagenet.lu;
publicclassHelloJNI{
static{
System.loadLibrary("HelloJNI");
}
publicnativestaticintget();
publicnativestaticvoidset(inti);
publicstaticvoidmain(String[]args){
HelloJNItest=newHelloJNI();
test.set(10);
System.out.println(test.get());
}
}
2、在HelloJNI.java文件所在目錄下編譯.java文件。
javacHelloJNI.java
3、生成.h頭文件,需要注意的是,要在src目錄層生成文件
...src]#javah-jninet.lu.HelloJNI
4、編寫.c文件
#include"net_wangliping_HelloJNI.h"
inti=0;
JNIEXPORTjintJNICALLJava_net_wangliping_HelloJNI_get(JNIEnv*env,jclassjc)
{
returni;
}
JNIEXPORTvoidJNICALLJava_net_wangliping_HelloJNI_set(JNIEnv*env,jclassjc,jintj)
{
i=2*j;
}
5、生成.so文件
[root@turbolinuxsrc]#gcc-I/usr/java/jdk1.5.0_13/include/linux-I/usr/java/jdk1.5.0_13/include-fPIC-shared-olibHelloJNI.soHelloJNI.c
6、eclipse調用SO文件
最簡單的方式,調用System.out.println(System.getProperty("java.library.path"));
得到/usr/java/jdk1.5.0_13/jre/lib/i386,將SO文件放在該目錄下
運行java程序,輸出了由C語言函數計算出的結果
『捌』 java調用so方法如何返回對象
雖然Java 嚴格按照值傳遞,但是精確的效果在傳遞基本類型還是引用類型之間是不同的。
當我們將一個原始類型傳遞給一個方法時,它將按值傳遞。但是當我們將一個對象傳遞給一個方法時,情況會發生巨大的變化,因為對象是通過有效調用的方式傳遞的。Java做這個有趣的事情,這是一種混合傳遞值和傳遞引用。基本上,函數不能更改參數,但函數可以通過調用其中的某些方法來讓參數自行更改。
在創建類類型的變數時,我們只創建一個對象的引用。因此,當我們將此引用傳遞給方法時,接收它的參數將引用與參數引用的對象相同的對象。
這實際上意味著對象的行為就好像通過使用引用調用來傳遞給方法一樣。
方法內部對象的改變確實反映在用作參數的對象中。
在Java中,我們可以將對象傳遞給方法。例如,請考慮以下程序:
// Java program to demonstrate objects
// passing to methods.
class ObjectPassDemo
{
int a, b;
ObjectPassDemo(int i, int j)
{
a = i;
b = j;
}
// return true if o is equal to the invoking
// object notice an object is passed as an
// argument to method
boolean equalTo(ObjectPassDemo o)
{
return (o.a == a && o.b == b);
}
}
// Driver class
public class Test
{
public static void main(String args[])
{
ObjectPassDemo ob1 = new ObjectPassDemo(100, 22);
ObjectPassDemo ob2 = new ObjectPassDemo(100, 22);
ObjectPassDemo ob3 = new ObjectPassDemo(-1, -1);
System.out.println("ob1 == ob2: " + ob1.equalTo(ob2));
System.out.println("ob1 == ob3: " + ob1.equalTo(ob3));
}
}
輸出:
ob1 == ob2:true
ob1 == ob3:false
創建了三個對象'ob1','ob2'和'ob3':
ObjectPassDemo ob1 = new ObjectPassDemo(100,22);
ObjectPassDemo ob2 = new ObjectPassDemo(100,22);
ObjectPassDemo ob3 = new ObjectPassDemo(-1,-1);
在方法方面,聲明了一個名為a的Foo類型的引用,並且它的初始值為null。
boolean equalTo(ObjectPassDemo o);
當我們調用方法equalTo時,引用'o'將被分配給作為參數傳遞的對象,即'o'將引用'ob2'作為以下語句執行。
System.out.println(「ob1 == ob2:」+ ob1.equalTo(ob2));
現在我們可以看到,'ob1'上調用了equalTo方法,'o'指的是'ob2'。由於'a'和'b'的值對於兩個引用都是相同的,所以如果(條件)為真,那麼將返回布爾值true。
if(oa == a && ob == b)
執行以下語句時,'o'將重新分配給'ob3'。
System.out.println(「ob1 == ob3:」+ ob1.equalTo(ob3));
現在我們可以看到,'ob1'上調用了equalTo方法,'o'指的是'ob3'。由於'a'和'b'的值對於兩個引用都不相同,所以如果(條件)為假,那麼else塊將執行並且將返回false。
定義一個將其類的對象作為參數的構造函數
對象參數最常見的用途之一是構造函數。通常,在實踐中,需要構建一個新對象,以便它最初與某個現有對象相同。為此,我們可以使用Object.clone()方法或定義一個將其類的對象作為參數的構造函數。下面的例子說明了第二個選項:
// Java program to demonstrate one object to
// initialize another
class Box
{
double width, height, depth;
// Notice this constructor. It takes an
// object of type Box. This constructor use
// one object to initialize another
Box(Box ob)
{
width = ob.width;
height = ob.height;
depth = ob.depth;
}
// constructor used when all dimensions
// specified
Box(double w, double h, double d)
{
width = w;
height = h;
depth = d;
}
// compute and return volume
double volume()
{
return width * height * depth;
}
}
// driver class
public class Test
{
public static void main(String args[])
{
// creating a box with all dimensions specified
Box mybox = new Box(10, 20, 15);
// creating a of mybox
Box myclone = new Box(mybox);
double vol;
// get volume of mybox
vol = mybox.volume();
System.out.println("Volume of mybox is " + vol);
// get volume of myclone
vol = myclone.volume();
System.out.println("Volume of myclone is " + vol);
}
}
輸出:
Volume of mybox is 3000.0
Volume of myclone is 3000.0
返回對象
在java中,一個方法可以返回任何類型的數據,包括對象。例如,在以下程序中,incrByTen()方法返回一個對象,其中(整數變數)的值比調用對象中的值大10。
// Java program to demonstrate returning
// of objects
class ObjectReturnDemo
{
int a;
ObjectReturnDemo(int i)
{
a = i;
}
// This method returns an object
ObjectReturnDemo incrByTen()
{
ObjectReturnDemo temp =
new ObjectReturnDemo(a+10);
return temp;
}
}
// Driver class
public class Test
{
public static void main(String args[])
{
ObjectReturnDemo ob1 = new ObjectReturnDemo(2);
ObjectReturnDemo ob2;
ob2 = ob1.incrByTen();
System.out.println("ob1.a: " + ob1.a);
System.out.println("ob2.a: " + ob2.a);
}
}
輸出:
ob1.a:2
ob2.a:12