導航:首頁 > 編程語言 > 靜態java庫

靜態java庫

發布時間:2023-10-30 05:50:42

『壹』 androidjava靜態庫和java共享庫有什麼區別

程序編制一般需經編輯、編譯、鏈接、載入和運行幾個步驟。在我們的應用中,有一些公共代碼是需要反復使用,就把這些代碼編譯為「庫」文件;在鏈接步驟中,連接器將從庫文件取得所需的代碼,復制到生成的可執行文件中。這種庫稱為靜態庫,其特點是可執行文件中包含了庫代碼的一份完整拷貝;缺點就是被多次使用就會有多份冗餘拷貝。

為了克服這個缺點可以採用動態鏈接庫。這個時候鏈接器僅僅是在可執行文件中打上標志,說明需要使用哪些動態連接庫;當運行程序時,載入器根據這些標志把所需的動態鏈接庫載入到內存。

另外在當前的編程環境中,一般都提供方法讓程序在運行的時候把某個特定的動態連接庫載入並運行,也可以將其卸載(例如Win32的LoadLibrary()&FreeLibrary()和Posix的dlopen()&dlclose())。這個功能被廣泛地用於在程序運行時刻更新某些功能模塊或者是程序外觀。

與普通程序不同的是,Java程序(class文件)並不是本地的可執行程序。當運行Java程序時,首先運行JVM(Java虛擬機),然後再把Java class載入到JVM里頭運行,負責載入Java class的這部分就叫做Class Loader。通常class文件僅在需要使用時才載入。 這本身就是一種動態鏈接。
Java作為一種天生的動態鏈接語言,無法支持靜態鏈接。但C語言的靜態庫除了靜態鏈接的概念外,還隱含了一層意思,即庫中的代碼會打包到可執行文件中。JAVA中的JAR某種程度上類似一個可執行文件或庫,借用C語言中靜態庫和動態庫的概念,這里把最終會合並到生成的JAR文件中的JAR包叫靜態庫,反之僅僅在編譯中使用,並不打包到生成的JAR包中,運行時需系統自行提供的JAR包叫動態庫。
C的靜態鏈接只把需要的代碼復制過來,而Java用類似Fat Jar的方法,把所有的依賴庫打包到最後的庫中,眉毛鬍子一把抓。這個問題可以用ProGuard解決,用它自己的話說是 It detects and removes unused classes, fields, methods, and attributes。

Eclipse中對JAR包的使用方式有兩種,library和user libraries,其中library在工程中通過add jars...或add external jars...添加,出現在Referenced Libraries中,而user libraries需要在工作空間中管理,再在工程中通過add library...添加。這兩種使用方式本身並沒有靜態庫和動態庫的區別,需要在打包或部署時再行指定。但user libraries的方式明顯更方便管理多個工程共同使用的多個庫,而系統庫往往都有這種特性。
android的apk比JAR更類似可執行程序,而且因為標准庫隱藏了很多功能,我們常常需要使用自己構建的系統庫來編譯。但android的ADT工具並沒有提供是否將library或user libraries打包的選項。根據我的經驗,ADT默認將library打包到apk中,而user libraries則僅用於編譯,運行時再請求系統載入相關類。哪位同學有更明確的信息,還望指教,我短期內恐怕不會有時間去研究這個問題。
因此,可以這么說,在android中,library用來添加靜態庫,而user libraries用來管理動態庫。千萬不能弄錯了,如果把靜態庫錯誤地加入動態庫,運行時會出現找不到對應的class的錯誤,但因為Java語言的動態鏈接機制,只有運行到庫中代碼時才會出錯;反之,如果把動態庫做成了靜態庫,問題就更隱蔽了,可能只是dex文件特別大,而沒有其它問題,也可能因載入了錯誤版本的系統代碼,出現一些稀奇古怪的問題。慎之,慎之...
附:向eclispe中添加user Libraries的步驟:
1。點擊eclipse的window菜單,選擇「Preference」
2。在preferences窗口中選擇java->User Libraries,然後點擊窗口右邊的New...按鈕,在彈出的子窗口中輸入user library的名稱,此時在user libraries窗口中會出現新加的library名稱。
3。向該user library中添加jar包。選中my_lib,然後點擊Add JARS...按鈕,選擇你要添加的jar後,點擊「打開」按鈕,則my_lib庫中就會出現你剛添加的jar文件信息。
4。最後點擊窗口下的「OK」按鈕,完成user library的添加和其jar的添加。

『貳』 java 如何調用一個已經存在的靜態庫,並輸入和獲取參數! 例如:靜態庫中已經存在函數 ret=ys_tpcall(aa);

給出一個windows下dll的實例。linux下.a的靜態庫只是頭文件和編譯有所不同,另外需要將編譯後的動態庫文件放入/usr/lib下,使用ldconfig載入。
一 先製作一個系統中有的DLL文件(cpp給出的sdk介面)

既然是測試我們就把我們這個dll叫做testDll吧,為了簡單其間,我只寫一個add方法,就是簡單的2個數字相加,對於真正的開發中我們肯定會遇到其他類型,java到c/cpp中類型需要轉換,具體類型轉換對應關系g一下就能得到,我也不在列舉。c/cpp中一個class一般包含2個文件,一個頭文件定義(*.h),一個文件主體(*.c/*.cpp)。啰嗦了這么多還是直接動手吧,先在vs2008中建立一個工程(當然你也可以直接編寫不用這些IDE工具,gcc g++的命令自己g。下同,不在注釋不在廢話),選取win32工程

鍵入工程名字testDll,點擊next選取DLL,然後點擊完成

打開我們的testdll.cpp,添加進我們的add方法

C++代碼
1.int add(int a,int b){
2. return a+b;
3.}
int add(int a,int b){
return a+b;
}
注意到文件列表裡並沒有testDll.h,因為我們要給出調用者一個介面,如果不給頭文件,人家就沒辦法調用,所以我們就必須添加一個頭文件testDll.h。

C++代碼
1.#ifdef TEST_DLL
2.#define TEST_API __declspec(dllexport)
3.#else
4.#define TEST_API __declspec(dllimport)
5.#endif
6.
7./* Set up for C function definitions, even when using C++ */
8.#ifdef __cplusplus
9.extern "C" {
10.#endif
11.
12.TEST_API int add(int,int);
13.
14./* Ends C function definitions when using C++ */
15.#ifdef __cplusplus
16.}
17.#endif
#ifdef TEST_DLL
#define TEST_API __declspec(dllexport)
#else
#define TEST_API __declspec(dllimport)
#endif

/* Set up for C function definitions, even when using C++ */
#ifdef __cplusplus
extern "C" {
#endif

TEST_API int add(int,int);

/* Ends C function definitions when using C++ */
#ifdef __cplusplus
}
#endif
在這個頭文件中我們把我們的add方法給定義了進去。注意到testdll.cpp中#include "stdafx.h",所以我們就把這個testDll.h include進stdafx.h裡面。

按道理說我們的這個dll已經完成了,但是一般c/cpp給介面SDK的時候大都給.h和.lib,為了一步生成dll和lib,我們添加進一個testDll.def,有了這個文件就可以一步生成dll和lib。在source file里右鍵add new item ,選擇Mole-Definition File

鍵入testDll,OK了,我們可以直接build了。生成testDll.dll和testDll.lib。

把testDll.dll扔到system32目錄里等待我們高大威猛的java jni調用。

二 JNI

2.1 編寫java文件

為了顯示我們的與眾相同,我們就把我們的這個java文件命名為Demo.java順便直接帶上包名
,因為我們知道人家給我們的介面里有個add方法,所以我們就直接來個調用吧。
Java代碼
1.package com.testJni.testDemo;
2.
3.public class Demo {
4. static
5. {
6. //System.out.println(System.getProperty("java.library.path"));
7. System.loadLibrary("testDll");
8. System.loadLibrary("jniDll");
9. }
10. public native static int add(int a,int b);
11.
12.}
package com.testJni.testDemo;

public class Demo {
static
{
//System.out.println(System.getProperty("java.library.path"));
System.loadLibrary("testDll");
System.loadLibrary("jniDll");
}
public native static int add(int a,int b);

}
demo.java代碼暫時如此,我們把將要生成的jni的dll叫做jniDll,有童鞋講,我不想用你這個爛名字jniDll多俗啊,沒關系,你可以換,隨你換,生成文件後你再換也可以,現在換也可以。

2.2 生成.h頭文件

javah命令,不多講。生成的文件com_testJni_testDemo_Demo.h這個文件的命名規則我就不多講了,一目瞭然。

C++代碼
1./* DO NOT EDIT THIS FILE - it is machine generated */
2.#include <jni.h>
3./* Header for class com_testJni_testDemo_Demo */
4.
5.#ifndef _Included_com_testJni_testDemo_Demo
6.#define _Included_com_testJni_testDemo_Demo
7.#ifdef __cplusplus
8.extern "C" {
9.#endif
10./*
11. * Class: com_testJni_testDemo_Demo
12. * Method: add
13. * Signature: (II)I
14. */
15.JNIEXPORT jint JNICALL Java_com_testJni_testDemo_Demo_add
16. (JNIEnv *, jclass, jint, jint);
17.
18.#ifdef __cplusplus
19.}
20.#endif
21.#endif
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_testJni_testDemo_Demo */

#ifndef _Included_com_testJni_testDemo_Demo
#define _Included_com_testJni_testDemo_Demo
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: com_testJni_testDemo_Demo
* Method: add
* Signature: (II)I
*/
JNIEXPORT jint JNICALL Java_com_testJni_testDemo_Demo_add
(JNIEnv *, jclass, jint, jint);

#ifdef __cplusplus
}
#endif
#endif

2.3 用c/cpp實現這個頭文件

c/cpp中已經實現了這個add方法,我們只需要調用就可以啦。所以直接vs2008中建立一個dll工程,工程名我們就叫jniDll,具體過程不再多講,方法同上面testDll的建立一樣。在這個工程里kimmking把需要引用的包、文件等已經講的很清楚了。打開jniDll.cpp,添加下面代碼

C++代碼
1.JNIEXPORT jint JNICALL Java_com_testJni_testDemo_Demo_add
2.(JNIEnv *env,jclass jobject,jint a,jint b){
3.
4. return add(a,b);
5.}
JNIEXPORT jint JNICALL Java_com_testJni_testDemo_Demo_add
(JNIEnv *env,jclass jobject,jint a,jint b){

return add(a,b);
}因為int對應的類型就剛好是jint,所以就不需要轉換,其他需要轉換的類型自己g對應關系轉換,注意釋放。

這個工程里我們還需要打開 stdafx.h添加
C++代碼
1.#include <jni.h>
2.
3.#include "testDll.h"
4.#include "com_testJni_testDemo_Demo.h"
#include <jni.h>

#include "testDll.h"
#include "com_testJni_testDemo_Demo.h"

在編譯這個jniDll工程的時候需要引入testDll.h,com_testJni_testDemo_Demo.h,另外添加testDll.lib這個依賴。

好了做好這些後,build下,生成了我們期待已久的jniDll.dll,把這個dll同樣扔到system32下。

三 測試

本人特懶,不想寫多餘的class,所以直接修改Demo.java 這也是剛才為什麼講暫時如此的原因
Java代碼
1.package com.testJni.testDemo;
2.
3.public class Demo {
4. static
5. {
6. //System.out.println(System.getProperty("java.library.path"));
7. System.loadLibrary("testDll");
8. System.loadLibrary("jniDll");
9. }
10. public native static int add(int a,int b);
11. public static void main(String[] args) {
12. System.out.println(add(7,2));
13. }
14.}
package com.testJni.testDemo;

public class Demo {
static
{
//System.out.println(System.getProperty("java.library.path"));
System.loadLibrary("testDll");
System.loadLibrary("jniDll");
}
public native static int add(int a,int b);
public static void main(String[] args) {
System.out.println(add(7,2));
}
}

四 最後補充

如果系統已經載入過c/cpp的dll,我們就不用再System.loadLibrary("testDll")了,載入一遍就可以了,因為我們剛才寫的testDll系統沒有載入,所以我就載入了一下。對於多個dll可以寫多個System.loadLibrary去載入,修改static{}裡面的內容不需要重新生成dll,除非你多加了一個調用方法,如果你看清楚規則,就不用javah命令就可以直接編寫頭文件,用javah太麻煩了。

『叄』 java中static的用法

static可以修飾變數(屬性)、方法、代碼塊和內部類

  1. static屬性:屬於這個類所有,即由該類創建的所有對象共享同一個static屬性。可以對象創建後通過對象名.屬性名類名.屬性名兩種方式來訪問。也可以在沒有創建任何對象之前通過類名.屬性名的方式來訪問。

  2. static方法:也可以通過對象名.方法名和類名.方法名兩種方式來訪問

  3. static代碼塊:當類被第一次使用時(可能是調用static屬性和方法,或者創建其對象)執行靜態代碼塊,且只被執行一次,主要作用是實現static屬性的初始化。

  4. static內部類:屬於整個外部類,而不是屬於外部類的每個對象。不能訪問外部類的非靜態成員(變數或者方法),.可以訪問外部類的靜態成員

閱讀全文

與靜態java庫相關的資料

熱點內容
智能網路攝像頭加密 瀏覽:570
軟體畢業程序員培訓 瀏覽:650
安卓陀螺儀低怎麼辦 瀏覽:245
一級建造師復習題集pdf 瀏覽:901
法理學pdf海默 瀏覽:390
伺服器內存儲器是用什麼的 瀏覽:817
微幫同城分類信息源碼 瀏覽:806
安卓系統ad是什麼 瀏覽:471
python輸出中不加佔位符 瀏覽:594
linux文件夾許可權控制 瀏覽:728
雅虎郵箱怎麼加密碼 瀏覽:819
為什麼安卓手機登錄不了蘋果賬號 瀏覽:535
如何復制usb加密狗 瀏覽:799
哪個app看你微笑時很美 瀏覽:908
mac啟動命令 瀏覽:602
ngc伺服器是什麼的簡稱 瀏覽:73
深度系統如何創建文件夾 瀏覽:847
臨汾單片機步進電機驅動電路 瀏覽:76
全新勝達天窗能編程嗎 瀏覽:320
ug常用命令 瀏覽:349