- 相關(guān)推薦
JNI是怎樣java調(diào)用c動態(tài)庫
JNI是什么 java調(diào)用c動態(tài)庫
JNI是JavaNativeInterface的縮寫,中文為JAVA本地調(diào)用。從Java1.1開始,JavaNativeInterface(JNI)標(biāo)準(zhǔn)成為java平臺的一部分,它允許Java代碼和其他語言寫的代碼進(jìn)行交互。JNI一開始是為了本地已編譯語言,尤其是C和C++而設(shè)計的,但是它并不妨礙你使用其他語言,只要調(diào)用約定受支持就可以了。
使用java與本地已編譯的代碼交互,通常會喪失平臺可移植性。但是,有些情況下這樣做是可以接受的,甚至是必須的,比如,使用一些舊的庫,與硬件、操作系統(tǒng)進(jìn)行交互,或者為了提高程序的性能。JNI標(biāo)準(zhǔn)至少保證本地代碼能工作在任何Java虛擬機(jī)實現(xiàn)下。
編寫帶有native聲明的方法的java類
·使用javac命令編譯所編寫的java類
·使用javah?jnijava類名生成擴(kuò)展名為h的頭文件
·使用C/C++實現(xiàn)本地方法
·將C/C++編寫的文件生成動態(tài)連接庫
·ok
1)編寫java程序:這里以HelloWorld為例。
代碼1:
classHelloWorld{
publicnativevoiddisplayHelloWorld();
static{
System.loadLibrary("hello");
publicstaticvoidmain(String[]args){
newHelloWorld().displayHelloWorld();
聲明native方法:如果你想將一個方法做為一個本地方法的話,那么你就必須聲明改方法為native的,并且不能實現(xiàn)。其中方法的參數(shù)和返回值在后面講述。Load動態(tài)庫:System.loadLibrary("hello");加載動態(tài)庫(我們可以這樣理解:我們的方法displayHelloWorld()沒有實現(xiàn),但是我們在下面就直接使用了,所以必須在使用之前對它進(jìn)行初始化)這里一般是以static塊進(jìn)行加載的。同時需要注意的是System.loadLibrary();的參數(shù)“hello”是動態(tài)庫的名字。
2)編譯
沒有什么好說的了javacHelloWorld.java
3)生成擴(kuò)展名為h的頭文件javah?
jniHelloWorld頭文件的內(nèi)容:/*DONOTEDITTHISFILE-itismachinegenerated*/
1.include
/*HeaderforclassHelloWorld*/
1.ifndef_Included_HelloWorld
2.define_Included_HelloWorld
3.ifdef__cplusplus
extern"C"{
1.endif
*Class:HelloWorld
*Method:displayHelloWorld
*Signature:()V
JNIEXPORTvoidJNICALLJava_HelloWorld_displayHelloWorld(JNIEnv*,jobject);
1.ifdef__cplusplus
1.endif
2.endif
(這里我們可以這樣理解:這個h文件相當(dāng)于我們在java里面的接口,這里聲明了一個Java_HelloWorld_displayHelloWorld(JNIEnv*,jobject);方法,然后在我們的本地方法里面實現(xiàn)這個方法,也就是說我們在編寫C/C++程序的時候所使用的方法名必須和這里的一致)。
4)編寫本地方法實現(xiàn)和由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頭文件引入(我是這么理解的:相當(dāng)于我們在編寫java程序的時候,實現(xiàn)一個接口的話需要聲明才可以,這里就是將HelloWorld.h頭文件里面聲明的方法加以實現(xiàn)。當(dāng)然不一定是這樣)。然后保存為HelloWorldImpl.c就ok了。
5)生成動態(tài)庫
這里以在Windows中為例,需要生成dll文件。在保存HelloWorldImpl.c文件夾下面,使用VC的編譯器cl成。cl-I%java_home%include-I%java_home%includewin32-LDHelloWorldImp.c-Fehello.dll注意:生成的dll文件名在選項-Fe后面配置,這里是hello,因為在HelloWorld.java文件中我們loadLibary的時候使用的名字是hello。當(dāng)然這里修改之后那里也需要修改。另外需要將-I%java_home%include-I%java_home%includewin32參數(shù)加上,因為在第四步里面編寫本地方法的時候引入了jni.h文件。
6)運(yùn)行程序javaHelloWorld就ok.
下面是一個簡單的例子實現(xiàn)打印一句話的功能,但是用的c的printf最終實現(xiàn)。一般提供給java的jni接口包括一個so文件(封裝了c函數(shù)的實現(xiàn))和一個java文件(需要調(diào)用path的類)。
1.JNI的目的是使java方法中能夠調(diào)用c實現(xiàn)的一些函數(shù),比如以下的java類,就需要調(diào)用一個本地函數(shù)testjni(一般聲明為privatenative類型),首先需要創(chuàng)建文件weiqiong.java,內(nèi)容如下:
classweiqiong{static{System.loadLibrary("testjni");//載入靜態(tài)庫,test函數(shù)在其中實現(xiàn)}privatenativevoidtestjni();//聲明本地調(diào)用publicvoidtest(){testjni();}publicstaticvoidmain(Stringargs[]){weiqionghaha=newweiqiong();haha.test();}}
2.然后執(zhí)行javacweiqiong.java,如果沒有報錯,會生成一個weiqiong.class。
3.然后設(shè)置classpath為你當(dāng)前的工作目錄,如直接輸入命令行:setclasspath=weiqiong.class所在的完整目錄(如c: est)再執(zhí)行javahweiqiong,會生成一個文件weiqiong.h文件,其中有一個函數(shù)的聲明如下:
JNIEXPORTvoidJNICALLJava_weiqiong_testjni(JNIEnv*,jobject);
4.創(chuàng)建文件testjni.c將上面那個函數(shù)實現(xiàn),內(nèi)容如下:
1.include
2.include
JNIEXPORTvoidJNICALLJava_weiqiong_testjni(JNIEnv*env,jobjectobj){printf("haha---------gointoc!!! ");}
5.為了生成.so文件,創(chuàng)建makefile文件如下:
libtestjni.so:testjni.omakefilegcc-Wall-rdynamic-shared-olibtestjni.sotestjni.otestjni.o:testjni.cweiqiong.hgcc-Wall-ctestjni.c-I./-I/usr/java/j2sdk1.4.0/include-I/usr/java/j2sdk1.4.0/include/linuxcl:rm-rf*.o*.so注意:gcc前面是tab空,j2sdk的目錄根據(jù)自己裝的j2sdk的具體版本來寫,生成的so文件的名字必須是loadLibrary的參數(shù)名前加“l(fā)ib”。
6.exportLD_LIBRARY_PATH=.,由此設(shè)置library路徑為當(dāng)前目錄,這樣java文件才能找到so文件。一般的做法是將so文件copy到本機(jī)的LD_LIBRARY_PATH目錄下。
7.執(zhí)行javaweiqiong,打印出結(jié)果:“haha---------gointoc!!!”
javascript 中(function{})()這種寫法什么意思?
最近在整理javascript 學(xué)習(xí),發(fā)現(xiàn)這個問題了 ,在網(wǎng)上發(fā)現(xiàn)這么個解釋 最清楚 最明白 ;
(function(){})()
相當(dāng)于先定義 function xx(){},后調(diào)用 xx();
()是最高優(yōu)先級的,所以先執(zhí)行function(){},
這個定義了一個匿名函數(shù),等于xx=function(www.diannao114.cn){}
接著就是調(diào)用xx()了;
給個例子
JScript codefunctionf1(a)
{ alert(a);
functionf2(a)
{ returnfunction(){ alert(a); }
}這里的var x=f2 就等于把函數(shù)傳遞給了f2,然后要執(zhí)行這個函數(shù),就必須加() 也就是x();
也就是f2()
還是(function f2(a){
return function(){
alert(a);
另外還有一個問題就是命名空間的問題
YY = YY||{};---聲明一個叫YY的命名空間(定義一個全局的變量)
(function() {
YY.Lang=function() {------聲明一個叫YY.Lang的命名空間(通過全局變量的增加屬性的方式把閉包里的對象傳到全局變量中,實現(xiàn)代碼封裝的效果)
isUndefined: function(o) {
return typeof o === 'undefined';
isString: function(o) {
return typeof o === 'string';
---調(diào)用方法
alert(YY.Lang.isString('test me'));
這時候就有人不明了,樓上為什么要加(function() { 和)(); 最外面的這兩行,有什么用啊?
JScript codeYY=YY||{}; //---聲明一個叫YY的命名空間(定義一個全局的變量)
function() { YY.Lang=function() {
//------聲明一個叫YY.Lang的命名空間(通過全局變量的增加屬性的方式把閉包里的對象傳到全局變量中,實現(xiàn)代碼封裝的效果) isUndefined:function(o) {returntypeofo==='undefined'; },
isString:function(o) {returntypeofo==='string'; } }; }
//---調(diào)用方法
alert(YY.Lang.isString('test me'));
疑問在這: 注釋掉這兩行有什么不一樣的呢?不就是申明嗎,為什么要用()()執(zhí)行一下啊?
答:
(function(){})()意思是立即執(zhí)行前一個括號里的function,相當(dāng)于是一個匿名函數(shù);由于里面的代碼的執(zhí)行,定義了YY.Lang這個對象,所以可以執(zhí)行alert(YY.Lang.isString('test me'));調(diào)用isString方法。
但是,如果按照你寫的
functionaa(){..};//只是定義了一個叫aa的函數(shù),但是并沒有執(zhí)行
alert(YY.Lang.isString('test me'));//執(zhí)行的時候會報找不到isString的方法。
這么寫有什么好處??
(function{})()的寫法有個好處,就是能很好的利用javascript的變量的可見范圍為執(zhí)行腳本時節(jié)省空間。例如以下寫法1和寫法2達(dá)到的目的是一樣的,但是寫法1的由于a變量的可見范圍只是在匿名函數(shù)體內(nèi),所以a在執(zhí)行完這個匿名函數(shù)后就釋放空間了。但是寫法2會一直存在該頁面中。
寫法1:
JScript code(function(){vara=2; alert(a); })();
寫法2:
JScript codevara=2; alert(a);
Java服務(wù)器軟件工程師試題
Java服務(wù)器軟件工程師試題一、 選擇題1. 欲構(gòu)造ArrayList類的一個實例,此類繼承了List接口,下列哪個方法是正確的 ( )A ArrayList myList=new Object(); B List myList=new ArrayList(); C ArrayList myList=new List(); D List myList=new List(); 2. paint()方法使用哪種類型的參數(shù)? ( )A Graphics B Graphics2D C String D Color 3. 指出下列程序運(yùn)行的結(jié)果( ) public class Example{ String str=new String("good"); char[]ch={'a','b','c'}; public static void main(String args[]){ Example ex=new Example(); ex.change(ex.str,ex.ch); System.out.print(ex.str+" and "); Sytem.out.print(ex.ch); } 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. 要從文件" file.dat"文件中讀出第10個字節(jié)到變量C中,下列哪個方法適合? ( )A FileInputStream in=new FileInputStream("file.dat"); in.skip(9); int c=in.read(); B FileInputStream in=new FileInputStream("file.dat"); in.skip(10); int c=in.read(); C FileInputStream in=new FileInputStream("file.dat"); int c=in.read(); D RandomAccessFile in=new RandomAccessFile("file.dat"); in.skip(9); int c=in.readByte(); 5. 給出下面代碼,那個語句是正確的?( )public class Person{ static int arr[] = new int[10]; public static void main(String a[]) { System.out.println(arr[1]); } } A 編譯時將產(chǎn)生錯誤; B 編譯時正確,運(yùn)行時將產(chǎn)生錯誤; C 輸出零; D 輸出空。 7. 執(zhí)行下面的hql查詢,關(guān)于返回值的說法,正確的是( ) select u.username,u.userid from com.x.entity.User u where u is not nullA語法錯誤,不能執(zhí)行B返回一個類型為List的實例C返回一個數(shù)組D當(dāng)返回結(jié)果只有一條時,返回一個數(shù)組8. 下面的程序執(zhí)行后沒有報錯,但數(shù)據(jù)總保存不到數(shù)據(jù)庫,最可能的原因 ( )public static void imain(String[] args){ SessionFactory sf=new Configration().configure().buildSessionFactory(); Session session=sf.openSession(); Medal medal=new Medal(); medal.setOwner(“totong”); medal.setType(“Gold medal”); session.save(user); session.close();}A配置文件配置有誤B沒有在配置文件中包含對映射文件的聲明C配置文件配置有誤D沒有對持久化操作捕捉異常E沒有開啟事務(wù)二、多項選擇題1. 執(zhí)行下列代碼后,哪個結(jié)論是正確的 String[] s=new String[10]; ( )A s[10] 為 ""; B s[9] 為 null; C s[0] 為 未定義 D s.length 為10 2. 下列哪個方法可用于創(chuàng)建一個可運(yùn)行的類? ( )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(){ ......} } E.public class X implements Thread{ public void run(){ ......} } 3. 下面哪個方法可以在任何時候被任何線程調(diào)用? ( )A notify() B wait() C notifyAll() D sleep() E.yield() F.synchronized(this) 4. 構(gòu)造BufferedInputStream的合適參數(shù)是哪個? ( )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 與數(shù)據(jù)庫建立連接B 通過JDBC-API向數(shù)據(jù)庫發(fā)送SQL語句C通過JDBC-API執(zhí)行SQL語句D進(jìn)行實體關(guān)系的映射 www.diannao114.cn7. Hibernate通過____接口,____接口和Type層次體系來訪問元數(shù)據(jù)。( )A ClassMetadataB CollectionMetadataC MetadataD CollectionMeta三,問答題1.執(zhí)行下列代碼后的結(jié)果是什么? int x,a=2,b=3,c=4; x=++a+b+++c++;2.簡述什么是設(shè)計模式,請描述你用過的幾種設(shè)計模式!3.從JAVA的角度理解,什么是重構(gòu)?5.abstractclass和interface有什么區(qū)別? 6.error和exception有什么區(qū)別?7.下列程序中構(gòu)造了一個SET并且調(diào)用其方法add(),輸出結(jié)果是?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(); set.add(new A()); set.add(new A()); set.add(new A()); System.out.println(set.size()); } } 8、請說出你所知道的線程同步的方法9、如果系統(tǒng)要使用超大整數(shù)(超過long長度范圍),請你設(shè)計一個數(shù)據(jù)結(jié)構(gòu)來存儲這種超大型數(shù)字以及設(shè)計一種算法來實現(xiàn)超大整數(shù)加法運(yùn)算
甲骨文分羹Android 谷歌借機(jī)升級"山寨"Java
導(dǎo)讀:近年來,各種專利訴訟案頻發(fā),各個廠商對自有專利的所有權(quán)和使用權(quán)越發(fā)的重視,一方是維護(hù)自己的權(quán)利、增加營收范圍,一方是防止同行分享自己辛苦的經(jīng)營成果,孰是孰非可謂見仁見智。
天極網(wǎng)4月26日消息,在4月25日的甲骨文起訴GoogleAndroid系統(tǒng)侵權(quán)案的審判中,一名Android前任工程師伯恩斯坦(DanBornstein)承認(rèn),去年在遭到起訴后,他曾負(fù)責(zé)在Android中移除了部分Java技術(shù)。
伯恩斯坦表示,Android是一個“活的項目”,隨時都在修改調(diào)整,并稱這部分Java技術(shù)是通過瑞士的一個軟件開發(fā)承包商N(yùn)oser帶到Android中的,當(dāng)時Android方面曾建議該公司哪些技術(shù)可以移植到Android,哪些則不可以。
(甲骨文分羹Android谷歌可借機(jī)升級“山寨”Java)
事件回顧
甲骨文在收購了Sun公司并獲得Java專利權(quán)后,于2010年8月將Google告上法庭,指控其Android操作系統(tǒng)侵犯了Java技術(shù)專利,并要求賠償10億美元。
在今年3月底,Google表示愿意向甲骨文支付兩項專利的2011年費(fèi)用,共計280萬美元。至于未來的賠償,Google提議將Android營收0.5%作為一項專利的費(fèi)用,此專利今年12月到期;另外將0.015%的營收作為第二項專利的費(fèi)用,此專利2018年4月到期。但甲骨文對此的回應(yīng)則是“Google開出的賠償額度太低了”。
Google表態(tài):所用技術(shù)無需授權(quán)
3月25日,“Android之父”Google高層安迪·魯賓也在法庭上作證,他強(qiáng)調(diào),“Android開發(fā)中所使用了Java部分不需要專利授權(quán)的技術(shù),所以無需支付專利費(fèi),也不需要獲得甲骨文的授權(quán)。”
有報道稱,在去年專利訴訟發(fā)生的前幾周,一封Google內(nèi)部郵件透露,當(dāng)時Google創(chuàng)始人拉里·佩吉(LarryPage)和塞爾吉·布林(SergeyBrin)曾要求“調(diào)查哪種技術(shù)可以成為Android中Java的替代方案”,而最終的討論結(jié)果是“我們尋找了許多方案都不行,因此得出結(jié)論:我們要商討Java授權(quán)。”
分羹Android
法庭文件披露,谷歌曾經(jīng)在2010年預(yù)測,到2013年,來自Android的相關(guān)收入(包括廣告、軟件產(chǎn)品、數(shù)字音樂消費(fèi)等)將會高達(dá)37億美元。
甲骨文如此大動干戈的索要Java技術(shù)授權(quán)費(fèi),一定程度上也是看準(zhǔn)了Android的巨大價值潛力,而Google方面千方百計的推脫責(zé)任,或許也是在為繼續(xù)尋求Java替代方案拖延時間,或者想要爭取更低的授權(quán)費(fèi)用。
近年來,各種專利訴訟案頻發(fā),各個廠商對自有專利的所有權(quán)和使用權(quán)越發(fā)的重視,一方是維護(hù)自己的權(quán)利、增加營收范圍,一方是防止同行分享自己辛苦的經(jīng)營成果,孰是孰非可謂見仁見智,而雙方為之付出的巨大精力和財力是顯而易見的。
隨著訴訟的發(fā)展進(jìn)程,Google方面并不占據(jù)優(yōu)勢,若最終甲骨文贏得官司,甲骨文則可獲得上億美元的專利費(fèi),而Google也有機(jī)會將其“山寨”Java升級為“正版”Java,對于Android系統(tǒng)的完善也不失是件好事。而目前Google最應(yīng)該做的就是想辦法說服甲骨文降低專利授權(quán)費(fèi)用。
Java語言中面向?qū)ο笫鞘裁匆馑?/p>
何謂面向?qū)ο笫鞘裁匆馑寄兀?/p>
面向?qū)ο蟪绦蛟O(shè)計是將人們認(rèn)識世界過程中普遍采用的思維方法應(yīng)用到程序設(shè)計中。對象是現(xiàn)實世界中存在的事物,它們是有形的,如某個人、某種物品;也可以是無形的,如某項計劃、某次商業(yè)交易。對象是構(gòu)成現(xiàn)實世界的一個獨(dú)立單位,人們對世界的認(rèn)識,是從分析對象的特征入手的。
對象的特征分為靜態(tài)特征和動態(tài)特征兩種。靜態(tài)的特征指對象的外觀、性質(zhì)、屬性等;動態(tài)的特征指對象具有的功能、行為等。客觀事物是錯綜復(fù)雜的,但人們總是從某一目的出發(fā),運(yùn)用抽象分析的能力,從眾多的特征中抽取最具代表性、最能反映對象本質(zhì)的若干特征加以詳細(xì)研究。
人們將對象的靜態(tài)特征抽象為屬性,用數(shù)據(jù)來描述,在Java語言中稱之為變量;人們將對象的動態(tài)特征抽象為行為,用一組代碼來表示,完成對數(shù)據(jù)的操作,在Java語言中稱之為方法,。一個對象由一組屬性和一組對屬性進(jìn)行操作的方法構(gòu)成。
Java語言優(yōu)點介紹
Java語言的優(yōu)點
Java語言是一種優(yōu)秀的編程語言。它最大的優(yōu)點就是與平臺無關(guān),在Windows 9x、Windows NT、Solaris、Linux、MacOS以及其它平臺上,都可以使用相同的代碼。“一次編寫,到處運(yùn)行”的特點,使其在互聯(lián)網(wǎng)上被廣泛采用。
由于Java語言的設(shè)計者們十分熟悉C++語言,所以在設(shè)計時很好地借鑒了C++語言。可以說,Java語言是一種比C++語言“還面向?qū)ο蟆钡囊环N編程語言。Java語言的語法結(jié)構(gòu)與C++語言的語法結(jié)構(gòu)十分相似,這使得C++程序員學(xué)習(xí)Java語言更加容易。
當(dāng)然,如果僅僅是對C++改頭換面,那么就不會有今天的Java熱了。Java語言提供的一些有用的新特性,使得使用Java語言比C++語言更容易寫出“無錯代碼”。
這些新特性包括:
1、提供了對內(nèi)存的自動管理,程序員無需在程序中進(jìn)行分配、釋放內(nèi)存,那些可怕的內(nèi)存分配錯誤不會再打擾設(shè)計者了;
2、去除了C++語言中的令人費(fèi)解、容易出錯的“指針”,用其它方法來進(jìn)行彌補(bǔ);
3、避免了賦值語句(如a = 3)與邏輯運(yùn)算語句(如a = = 3)的混淆;
4、取消了多重繼承這一復(fù)雜的概念。
【JNI是怎樣java調(diào)用c動態(tài)庫】相關(guān)文章:
如何在C語言中調(diào)用C++做的動態(tài)鏈接庫08-15
Java程序調(diào)用C/C++語言函數(shù)的方法07-31
怎樣創(chuàng)建Linux靜態(tài)庫和動態(tài)庫10-24