當前位置:才華齋>計算機>java語言>

JNI是怎樣java呼叫c動態庫

java語言 閱讀(4.36K)

JNI是什麼 java呼叫c動態庫

JNI是怎樣java呼叫c動態庫

JNI是JavaNativeInterface的縮寫,中文為JAVA本地呼叫。從Java1.1開始,JavaNativeInterface(JNI)標準成為java平臺的一部分,它允許Java程式碼和其他語言寫的程式碼進行互動。JNI一開始是為了本地已編譯語言,尤其是C和C++而設計的,但是它並不妨礙你使用其他語言,只要呼叫約定受支援就可以了。

使用java與本地已編譯的程式碼互動,通常會喪失平臺可移植性。但是,有些情況下這樣做是可以接受的,甚至是必須的,比如,使用一些舊的庫,與硬體、作業系統進行互動,或者為了提高程式的效能。JNI標準至少保證原生代碼能工作在任何Java虛擬機器實現下。

編寫帶有native宣告的方法的java類

·使用javac命令編譯所編寫的java類

·使用javah?jnijava類名生成副檔名為h的標頭檔案

·使用C/C++實現本地方法

·將C/C++編寫的檔案生成動態連線庫

·ok

1)編寫java程式:這裡以HelloWorld為例。

程式碼1:

classHelloWorld{

publicnativevoiddisplayHelloWorld();

static{

Library("hello");

publicstaticvoidmain(String[]args){

newHelloWorld()layHelloWorld();

宣告native方法:如果你想將一個方法做為一個本地方法的話,那麼你就必須宣告改方法為native的,並且不能實現。其中方法的引數和返回值在後面講述。Load動態庫:Library("hello");載入動態庫(我們可以這樣理解:我們的方法displayHelloWorld()沒有實現,但是我們在下面就直接使用了,所以必須在使用之前對它進行初始化)這裡一般是以static塊進行載入的。同時需要注意的是Library();的引數“hello”是動態庫的名字。

2)編譯

沒有什麼好說的了

3)生成副檔名為h的標頭檔案javah?

jniHelloWorld標頭檔案的內容:/*DONOTEDITTHISFILE-itismachinegenerated*/

ude

/*HeaderforclassHelloWorld*/

ef_Included_HelloWorld

ne_Included_HelloWorld

f__cplusplus

extern"C"{

f

*Class:HelloWorld

*Method:displayHelloWorld

*Signature:()V

JNIEXPORTvoidJNICALLJava_HelloWorld_displayHelloWorld(JNIEnv*,jobject);

f__cplusplus

f

f

(這裡我們可以這樣理解:這個h檔案相當於我們在java裡面的介面,這裡聲明瞭一個Java_HelloWorld_displayHelloWorld(JNIEnv*,jobject);方法,然後在我們的本地方法裡面實現這個方法,也就是說我們在編寫C/C++程式的時候所使用的方法名必須和這裡的一致)。

4)編寫本地方法實現和由javah命令生成的標頭檔案裡面宣告的方法名相同的方法。

程式碼2:

1#include"jni.h"

2#include"HelloWorld.h"

3//#includeotherheaders

4JNIEXPORTvoidJNICALLJava_HelloWorld_displayHelloWorld(JNIEnv*env,jobjectobj)

printf("Helloworld! ");

return;

注意程式碼2中的第1行,需要將jni.h(該檔案可以在%JAVA_HOME%/include資料夾下面找到)檔案引入,因為在程式中的JNIEnv、jobject等型別都是在該標頭檔案中定義的;另外在第2行需要將HelloWorld.h標頭檔案引入(我是這麼理解的:相當於我們在編寫java程式的時候,實現一個介面的話需要宣告才可以,這裡就是將HelloWorld.h標頭檔案裡面宣告的方法加以實現。當然不一定是這樣)。然後儲存為HelloWorldImpl.c就ok了。

5)生成動態庫

這裡以在Windows中為例,需要生成dll檔案。在儲存HelloWorldImpl.c資料夾下面,使用VC的編譯器cl成。cl-I%java_home%include-I%java_home%注意:生成的dll檔名在選項-Fe後面配置,這裡是hello,因為在檔案中我們loadLibary的時候使用的名字是hello。當然這裡修改之後那裡也需要修改。另外需要將-I%java_home%include-I%java_home%includewin32引數加上,因為在第四步裡面編寫本地方法的時候引入了jni.h檔案。

6)執行程式javaHelloWorld就ok.

下面是一個簡單的例子實現列印一句話的功能,但是用的c的printf最終實現。一般提供給java的jni介面包括一個so檔案(封裝了c函式的實現)和一個java檔案(需要呼叫path的類)。

1.JNI的目的是使java方法中能夠呼叫c實現的一些函式,比如以下的java類,就需要呼叫一個本地函式testjni(一般宣告為privatenative型別),首先需要建立檔案,內容如下:

classweiqiong{static{Library("testjni");//載入靜態庫,test函式在其中實現}privatenativevoidtestjni();//宣告本地呼叫publicvoidtest(){testjni();}publicstaticvoidmain(Stringargs[]){weiqionghaha=newweiqiong();();}}

2.然後執行,如果沒有報錯,會生成一個s。

3.然後設定classpath為你當前的工作目錄,如直接輸入命令列:setclasspath=s所在的完整目錄(如c: est)再執行javahweiqiong,會生成一個檔案weiqiong.h檔案,其中有一個函式的宣告如下:

JNIEXPORTvoidJNICALLJava_weiqiong_testjni(JNIEnv*,jobject);

4.建立檔案testjni.c將上面那個函式實現,內容如下:

ude

ude

JNIEXPORTvoidJNICALLJava_weiqiong_testjni(JNIEnv*env,jobjectobj){printf("haha---------gointoc!!! ");}

5.為了生成檔案,建立makefile檔案如下:

:tjni.o:-Wall-ctestjni.c-I./-I/usr/java/j2sdk1.4.0/include-I/usr/java/j2sdk1.4.0/include/linuxcl:rm-rf*.o*注意:gcc前面是tab空,j2sdk的目錄根據自己裝的j2sdk的具體版本來寫,生成的so檔案的名字必須是loadLibrary的引數名前加“lib”。

6.exportLD_LIBRARY_PATH=.,由此設定library路徑為當前目錄,這樣java檔案才能找到so檔案。一般的做法是將so檔案copy到本機的LD_LIBRARY_PATH目錄下。

7.執行javaweiqiong,打印出結果:“haha---------gointoc!!!”

javascript 中(function{})()這種寫法什麼意思?

最近在整理javascript 學習,發現這個問題了 ,在網上發現這麼個解釋 最清楚 最明白 ;

(function(){})()

相當於先定義 function xx(){},後呼叫 xx();

()是最高優先順序的,所以先執行function(){},

這個定義了一個匿名函式,等於xx=function(){}

接著就是呼叫xx()了;

給個例子

JScript codefunctionf1(a)

{ alert(a);

functionf2(a)

{ returnfunction(){ alert(a); }

}這裡的var x=f2 就等於把函式傳遞給了f2,然後要執行這個函式,就必須加() 也就是x();

也就是f2()

還是(function f2(a){

return function(){

alert(a);

另外還有一個問題就是名稱空間的問題

YY = YY||{};---宣告一個叫YY的名稱空間(定義一個全域性的變數)

(function() {

=function() {------宣告一個叫的名稱空間(通過全域性變數的增加屬性的方式把閉包裡的物件傳到全域性變數中,實現程式碼封裝的效果)

isUndefined: function(o) {

return typeof o === 'undefined';

isString: function(o) {

return typeof o === 'string';

---呼叫方法

alert(ring('test me'));

這時候就有人不明瞭,樓上為什麼要加(function() { 和)(); 最外面的這兩行,有什麼用啊?

JScript codeYY=YY||{}; //---宣告一個叫YY的名稱空間(定義一個全域性的變數)

function() { =function() {

//------宣告一個叫的名稱空間(通過全域性變數的增加屬性的方式把閉包裡的物件傳到全域性變數中,實現程式碼封裝的效果) isUndefined:function(o) {returntypeofo==='undefined'; },

isString:function(o) {returntypeofo==='string'; } }; }

//---呼叫方法

alert(ring('test me'));

疑問在這: 註釋掉這兩行有什麼不一樣的呢?不就是申明嗎,為什麼要用()()執行一下啊?

答:

(function(){})()意思是立即執行前一個括號裡的function,相當於是一個匿名函式;由於裡面的程式碼的執行,定義了這個物件,所以可以執行alert(ring('test me'));呼叫isString方法。

但是,如果按照你寫的

functionaa(){..};//只是定義了一個叫aa的函式,但是並沒有執行

alert(ring('test me'));//執行的時候會報找不到isString的方法。

這麼寫有什麼好處??

(function{})()的寫法有個好處,就是能很好的利用javascript的變數的可見範圍為執行指令碼時節省空間。例如以下寫法1和寫法2達到的目的是一樣的,但是寫法1的由於a變數的可見範圍只是在匿名函式體內,所以a在執行完這個匿名函式後就釋放空間了。但是寫法2會一直存在該頁面中。

寫法1:

JScript code(function(){vara=2; alert(a); })();

寫法2:

JScript codevara=2; alert(a);

Java伺服器軟體工程師試題

Java伺服器軟體工程師試題一、 選擇題1. 欲構造ArrayList類的一個例項,此類繼承了List介面,下列哪個方法是正確的 ( )A ArrayList myList=new Object(); B List myList=new ArrayList(); C ArrayList myList=new List(); D List myList=new List(); 2. paint()方法使用哪種型別的引數? ( )A Graphics B Graphics2D C String D Color 3. 指出下列程式執行的.結果( ) public class Example{ String str=new String("good"); char[]ch={'a','b','c'}; public static void main(String args[]){ Example ex=new Example(); ge(,); t(+" and "); t(); } public void change(String str,char ch[]){ str="test ok"; ch[0]='g'; } } A good and abc B good and gbc C test ok and abc D test ok and gbc 4. 要從檔案" "檔案中讀出第10個位元組到變數C中,下列哪個方法適合? ( )A FileInputStream in=new FileInputStream(""); (9); int c=(); B FileInputStream in=new FileInputStream(""); (10); int c=(); C FileInputStream in=new FileInputStream(""); int c=(); D RandomAccessFile in=new RandomAccessFile(""); (9); int c=Byte(); 5. 給出下面程式碼,那個語句是正確的?( )public class Person{ static int arr[] = new int[10]; public static void main(String a[]) { tln(arr[1]); } } A 編譯時將產生錯誤; B 編譯時正確,執行時將產生錯誤; C 輸出零; D 輸出空。 7. 執行下面的hql查詢,關於返回值的說法,正確的是( ) select name,id from u where u is not nullA語法錯誤,不能執行B返回一個型別為List的例項C返回一個數組D當返回結果只有一條時,返回一個數組8. 下面的程式執行後沒有報錯,但資料總儲存不到資料庫,最可能的原因 ( )public static void imain(String[] args){ SessionFactory sf=new Configration()igure()dSessionFactory(); Session session=Session(); Medal medal=new Medal(); wner(“totong”); ype(“Gold medal”); (user); e();}A配置檔案配置有誤B沒有在配置檔案中包含對對映檔案的宣告C配置檔案配置有誤D沒有對持久化操作捕捉異常E沒有開啟事務二、多項選擇題1. 執行下列程式碼後,哪個結論是正確的 String[] s=new String[10]; ( )A s[10] 為 ""; B s[9] 為 null; C s[0] 為 未定義 D th 為10 2. 下列哪個方法可用於建立一個可執行的類? ( )A public class X implements Runable{ public void run(){ ......} } B public class X implements Thread{ public void run(){ ......} } C public class X implements Thread{ public int run(){ ......} } D public class X implements Runable{ protected void run(){ ......} } ic class X implements Thread{ public void run(){ ......} } 3. 下面哪個方法可以在任何時候被任何執行緒呼叫? ( )A notify() B wait() C notifyAll() D sleep() d() hronized(this) 4. 構造BufferedInputStream的合適引數是哪個? ( )A BufferedInputStream B BufferedOutputStream C FileInputStream D FileOuterStream E. File 5. 指出下列哪個方法與方法public void add(int a){}為合理的過載方法。 ( )A public int add(int a) B public void add(long a) C public void add(int a,int b) D public void add(float a) 6. JDBC可以做哪三件 ( )A 與資料庫建立連線B 通過JDBC-API向資料庫傳送SQL語句C通過JDBC-API執行SQL語句D進行實體關係的對映 7. Hibernate通過____介面,____介面和Type層次體系來訪問元資料。( )A ClassMetadataB CollectionMetadataC MetadataD CollectionMeta三,問答題1.執行下列程式碼後的結果是什麼? int x,a=2,b=3,c=4; x=++a+b+++c++;2.簡述什麼是設計模式,請描述你用過的幾種設計模式!3.從JAVA的角度理解,什麼是重構?ractclass和interface有什麼區別? r和exception有什麼區別?7.下列程式中構造了一個SET並且呼叫其方法add(),輸出結果是?public class A{ public int hashCode(){return 1;} public Boolean equals(Object b){return true} public static void main(String args[]){ Set set=new HashSet(); (new A()); (new A()); (new A()); tln(()); } } 8、請說出你所知道的執行緒同步的方法9、如果系統要使用超大整數(超過long長度範圍),請你設計一個數據結構來儲存這種超大型數字以及設計一種演算法來實現超大整數加法運算

甲骨文分羹Android 谷歌藉機升級"山寨"Java

導讀:近年來,各種專利訴訟案頻發,各個廠商對自有專利的所有權和使用權越發的重視,一方是維護自己的權利、增加營收範圍,一方是防止同行分享自己辛苦的經營成果,孰是孰非可謂見仁見智。

天極網4月26日訊息,在4月25日的甲骨文起訴GoogleAndroid系統侵權案的審判中,一名Android前任工程師伯恩斯坦(DanBornstein)承認,去年在遭到起訴後,他曾負責在Android中移除了部分Java技術。

伯恩斯坦表示,Android是一個“活的專案”,隨時都在修改調整,並稱這部分Java技術是通過瑞士的一個軟體開發承包商Noser帶到Android中的,當時Android方面曾建議該公司哪些技術可以移植到Android,哪些則不可以。

(甲骨文分羹Android谷歌可藉機升級“山寨”Java)

事件回顧

甲骨文在收購了Sun公司並獲得Java專利權後,於2010年8月將Google告上法庭,指控其Android作業系統侵犯了Java技術專利,並要求賠償10億美元。

在今年3月底,Google表示願意向甲骨文支付兩項專利的2011年費用,共計280萬美元。至於未來的賠償,Google提議將Android營收0.5%作為一項專利的費用,此專利今年12月到期;另外將0.015%的營收作為第二項專利的費用,此專利2018年4月到期。但甲骨文對此的迴應則是“Google開出的賠償額度太低了”。

Google表態:所用技術無需授權

3月25日,“Android之父”Google高層安迪·魯賓也在法庭上作證,他強調,“Android開發中所使用了Java部分不需要專利授權的技術,所以無需支付專利費,也不需要獲得甲骨文的授權。”

有報道稱,在去年專利訴訟發生的前幾周,一封Google內部郵件透露,當時Google創始人拉里·佩吉(LarryPage)和塞爾吉·布林(SergeyBrin)曾要求“調查哪種技術可以成為Android中Java的替代方案”,而最終的討論結果是“我們尋找了許多方案都不行,因此得出結論:我們要商討Java授權。”

分羹Android

法庭檔案披露,谷歌曾經在2010年預測,到2013年,來自Android的相關收入(包括廣告、軟體產品、數字音樂消費等)將會高達37億美元。

甲骨文如此大動干戈的索要Java技術授權費,一定程度上也是看準了Android的巨大價值潛力,而Google方面千方百計的推脫責任,或許也是在為繼續尋求Java替代方案拖延時間,或者想要爭取更低的授權費用。

近年來,各種專利訴訟案頻發,各個廠商對自有專利的所有權和使用權越發的重視,一方是維護自己的權利、增加營收範圍,一方是防止同行分享自己辛苦的經營成果,孰是孰非可謂見仁見智,而雙方為之付出的巨大精力和財力是顯而易見的。

隨著訴訟的發展程序,Google方面並不佔據優勢,若最終甲骨文贏得官司,甲骨文則可獲得上億美元的專利費,而Google也有機會將其“山寨”Java升級為“正版”Java,對於Android系統的完善也不失是件好事。而目前Google最應該做的就是想辦法說服甲骨文降低專利授權費用。

Java語言中面向物件是什麼意思

何謂面向物件是什麼意思呢?

面向物件程式設計是將人們認識世界過程中普遍採用的思維方法應用到程式設計中。物件是現實世界中存在的事物,它們是有形的,如某個人、某種物品;也可以是無形的,如某項計劃、某次商業交易。物件是構成現實世界的一個獨立單位,人們對世界的認識,是從分析物件的特徵入手的。

物件的特徵分為靜態特徵和動態特徵兩種。靜態的特徵指物件的外觀、性質、屬性等;動態的特徵指物件具有的功能、行為等。客觀事物是錯綜複雜的,但人們總是從某一目的出發,運用抽象分析的能力,從眾多的特徵中抽取最具代表性、最能反映物件本質的若干特徵加以詳細研究。

人們將物件的靜態特徵抽象為屬性,用資料來描述,在Java語言中稱之為變數;人們將物件的動態特徵抽象為行為,用一組程式碼來表示,完成對資料的操作,在Java語言中稱之為方法,。一個物件由一組屬性和一組對屬性進行操作的方法構成。

Java語言優點介紹

Java語言的優點

Java語言是一種優秀的程式語言。它最大的優點就是與平臺無關,在Windows 9x、Windows NT、Solaris、Linux、MacOS以及其它平臺上,都可以使用相同的程式碼。“一次編寫,到處執行”的特點,使其在網際網路上被廣泛採用。

由於Java語言的設計者們十分熟悉C++語言,所以在設計時很好地借鑑了C++語言。可以說,Java語言是一種比C++語言“還面向物件”的一種程式語言。Java語言的語法結構與C++語言的語法結構十分相似,這使得C++程式設計師學習Java語言更加容易。

當然,如果僅僅是對C++改頭換面,那麼就不會有今天的Java熱了。Java語言提供的一些有用的新特性,使得使用Java語言比C++語言更容易寫出“無錯程式碼”。

這些新特性包括:

1、提供了對記憶體的自動管理,程式設計師無需在程式中進行分配、釋放記憶體,那些可怕的記憶體分配錯誤不會再打擾設計者了;

2、去除了C++語言中的令人費解、容易出錯的“指標”,用其它方法來進行彌補;

3、避免了賦值語句(如a = 3)與邏輯運算語句(如a = = 3)的混淆;

4、取消了多重繼承這一複雜的概念。