版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
1、JavaJava本地接口規(guī)1997年5月16日目錄1.簡(jiǎn)介Java本地接口概述背景JDK1.0本地方法接口Java運(yùn)行時(shí)接口原始本地接口和Java/COM接口目標(biāo)Java本地接口方法利用JNI編程JDK1.1.2中的變化2.設(shè)計(jì)概述JNI接口函數(shù)和指針加載和鏈接本地方法解析本地方法名本地方法的參數(shù)引用Java對(duì)象全局和局部引用實(shí)現(xiàn)局部引用訪問Java對(duì)象訪問基本類型數(shù)組訪問域和方法報(bào)告編程錯(cuò)誤Java異常異常和錯(cuò)誤代碼曰J-B曰吉異少異吊異常的處理3.JNI的類型和數(shù)據(jù)結(jié)構(gòu)基本類型引用類型域ID和方法ID值類型類型簽名UTF-8字符串4.JNI函數(shù)接口函數(shù)表版本信息GetVersion類操作D
2、efineClassFindClassGetSuperclassIsAssignableFrom異常ThrowThrowNewExceptionOccurredExceptionDescribeExceptionClearFatalError全局及局部引用NewGlobalRefDeleteGlobalRefDeleteLocalRef對(duì)象操作AllocObjectGetObjectClassIsInstanceOfIsSameObject訪問對(duì)象的域GetFieldIDGetField例程SetvtypeField例程調(diào)用實(shí)例方法GetMethodIDCallMethodCallNonvir
3、tualMethod訪問靜態(tài)域GetStaticFieldIDGetStaticField例程SetStaticField例程調(diào)用靜態(tài)方法GetStaticMethodIDCallStaticvtypeMethod字符串操作NewStringGetStringLengthGetStringCharsReleaseStringCharsNewStringUTFGetStringUTFLengthGetStringUTFCharsReleaseStringUTFChars數(shù)組操作GetArrayLengthNewObjectArrayGetObjectArrayElementSetObjectAr
4、rayElementNewvPrimitiveTypeArray例程GetvPrimitiveTypeArrayElements例程ReleasevPrimitiveTypeArrayElements例程GetvPrimitiveTypeArrayRegion例程SetvPrimitiveTypeArrayRegion例程注冊(cè)本地方法RegisterNativesUnregisterNatives監(jiān)視程序操作MonitorEnterMonitorExitJava虛擬機(jī)接口GetJavaVM5.調(diào)用API概述創(chuàng)建虛擬機(jī)連接虛擬機(jī)卸載虛擬機(jī)初始化結(jié)構(gòu)調(diào)用API函數(shù)JNIGetDefaultJava
5、VMInitArgsJNIGetCreatedJavaVMsJNICreateJavaVMDestroyJavaVMAttachCurrentThreadDetachCurrentThreadC+介紹JavaJava虛擬和匯編語言JavaNativeInterfaceJNIJNI編程接程語言C機(jī)(VM)內(nèi)部運(yùn))編寫的應(yīng)用程行的Java序和庫(kù)進(jìn)行代碼能夠與用其它編JNI處是它沒有對(duì)底層Java虛擬機(jī)的實(shí)現(xiàn)施加任何Java虛擬在不影響虛擬下添加對(duì)JNI的程序員只需編寫一種版本的本地應(yīng)用程序或庫(kù),就能夠與有支持JNI的Java虛擬機(jī)協(xié)論及以下主題Java標(biāo)JavaJNI編JDK1.1.2變Java盡
6、管可以完全用Java編寫應(yīng)用程序,但是有時(shí)單獨(dú)用Java不以處理那些能滿足應(yīng)用程序不能完全用Java程序員使用JNI編寫Java本編寫應(yīng)用例說明了何時(shí)需要使用Java本地方法:標(biāo)準(zhǔn)Java類庫(kù)不支持與平臺(tái)相關(guān)應(yīng)用程序所需的功能。已經(jīng)擁有了一個(gè)用另一種語言編寫庫(kù),而又希望通過JNI使Java代碼能夠訪問該庫(kù)。低級(jí)語言(如匯編語言)實(shí)現(xiàn)一段時(shí)限代碼。過JNI編程,可以創(chuàng)建、檢查及更新Java對(duì)象(包括數(shù)組和字符串)。調(diào)用Java方法+卜AXA-H-*AXA加載類和獲得類信息執(zhí)行運(yùn)行時(shí)類型檢查以與調(diào)用API一起使用JNI,以允許任意本地應(yīng)用程序嵌入到Java虛擬、ar./.這樣使得程序員能夠輕易地讓
7、已有應(yīng)用程序Java不必與虛擬機(jī)源碼相鏈這些法庫(kù)不同廠商的虛擬機(jī)提供了不同的本給定平臺(tái)上編寫、維護(hù)和分發(fā)多種JDK1.0本地方法接口Netscape的Java運(yùn)行時(shí)Java/COMMicrosoftJDK1.0JDK1.0附帶有本Java虛擬機(jī)。地方法接口。遺憾的是,有兩點(diǎn)原因使得該接口不適合第一,平臺(tái)相關(guān)碼將Java對(duì)象中的域作為C結(jié)構(gòu)的成員來進(jìn)訪問Java語言規(guī)范沒有規(guī)定在內(nèi)存中對(duì)象是Java擬機(jī)布局對(duì)象的方式有所不同,程序員就不不重新編譯本地方法庫(kù)。JDK1.0本地方法接口依賴于保unhand宏使得有必要以保守方式掃描本地堆棧。Java運(yùn)行時(shí)接口Netscape建議使用Java運(yùn)時(shí)(JR
8、I)Java擬機(jī)所提供服務(wù)的通JRI設(shè)計(jì)融入了可移植性-它幾乎沒有對(duì)底層Java虛擬機(jī)的實(shí)現(xiàn)細(xì)節(jié)作任何假設(shè)。JRI提出了各種各樣的問題,包、調(diào)試、反射、嵌入調(diào)(原始本地接口和Java/COM接口MicrosoftJava虛擬機(jī)支持兩種本地方法接口。在低一級(jí),它提供(RNI)RNI了與JDK本地方法接口有高度源代碼級(jí)們之間還進(jìn)行顯級(jí)MicrosoftJava/COM進(jìn)Java碼臺(tái)相關(guān)代碼必須用RNI函數(shù)來與垃圾收集為Java虛擬機(jī)提供了與語言無關(guān)的標(biāo)Java對(duì)象一樣來COM對(duì)Java類為COM類顯給統(tǒng)我們認(rèn)為統(tǒng)一的,經(jīng)過細(xì)致考慮的標(biāo)準(zhǔn)接口能夠向每個(gè)用戶提供以下好處:每個(gè)虛擬機(jī)臺(tái)相關(guān)代碼。工具構(gòu)造
9、器不必維護(hù)不應(yīng)用程序設(shè)計(jì)人員可以只編寫一種版關(guān)代碼就能夠在不同的虛擬機(jī)上運(yùn)行獲得標(biāo)準(zhǔn)本地方法聯(lián)合所有對(duì)Java虛擬機(jī)有興趣的當(dāng)事方。因此,我們?cè)贘ava獲得許可方之間組織了一系列研討會(huì),對(duì)設(shè)計(jì)統(tǒng)一的本地方法接口進(jìn)行了討論。研討會(huì)可標(biāo)準(zhǔn)本地方法接口必須滿足以下要求:二進(jìn)制兼容-主要的目標(biāo)是在給所有Java虛擬機(jī)實(shí)現(xiàn)之間實(shí)現(xiàn)本地法庫(kù)的二進(jìn)制兼對(duì)于給定平臺(tái),程序員只需要維護(hù)一種法庫(kù)。效率-若要支持時(shí)限代碼,法接口必須增加一點(diǎn)系統(tǒng)開銷。所有已虛擬機(jī)無關(guān)性(有二進(jìn)制兼容性)的技術(shù)都會(huì)占用一定的系統(tǒng)開銷我們必須與虛擬機(jī)無關(guān)性之間進(jìn)行某種折衷。功能-接口必須顯示足夠的Java虛擬機(jī)內(nèi)部情況以使本地方法能夠完
10、務(wù)Java我們希采用一種已有的方法作為標(biāo)口,因?yàn)檫@樣程序員(程序員不得不學(xué)習(xí)擬機(jī)中的多種接口)的工作負(fù)擔(dān)最輕。遺憾夠完全地滿足我們的目標(biāo)。Netscape的JRI最接近于我們所設(shè)因而我們采用它作為設(shè)計(jì)JRI的讀者將會(huì)到在API命名規(guī)則、ID似點(diǎn)雖。然我們進(jìn)行了JNI并具有對(duì)JRI的二進(jìn)制兼容性過虛擬機(jī)既JRIJNI。Microsoft的RNI是對(duì)JDK1.0的改進(jìn),因?yàn)樗梢苑椒ǖ膯栴}。然RNI作與虛擬機(jī)無關(guān)的本JDK類似,RNI本地方法Java對(duì)為C結(jié)構(gòu)來訪問。這導(dǎo)問題RNI將內(nèi)部Java對(duì)象的布局給了平臺(tái)相關(guān)代碼。Java對(duì)象作為C結(jié)構(gòu)直進(jìn)行訪問使得屏障是高級(jí)的垃作為進(jìn)標(biāo)COM擬機(jī)之間的完
11、全二進(jìn)制兼調(diào)COM求間接調(diào)用,而這幾乎不會(huì)占系統(tǒng)開銷。COM對(duì)象對(duì)動(dòng)態(tài)鏈接庫(kù)解本問題的方式也有很大的改進(jìn)。COM作標(biāo)準(zhǔn)Java本Java/COM如訪問私有Java/COM動(dòng)為Java對(duì)象提供標(biāo)準(zhǔn)的IUnknown和IDispatchCOM接臺(tái)相關(guān)代碼能夠訪問公有方法和域。遺憾的是IDispatch接口不能處理重載的Java方法,方法名稱時(shí)不區(qū)別小寫。另外,通過IDispatchJava方執(zhí)行動(dòng)態(tài)類型檢查和強(qiáng)制轉(zhuǎn)換。這是因?yàn)镮Dispatch接口的設(shè)計(jì)只考慮到弱類型的語言(BasicCOM許軟件組件(包全成熟的應(yīng)起工作,而不是處單個(gè)低層函數(shù)。我們認(rèn)為將所Java類或低層本地方法都當(dāng)作軟件組對(duì)CO
12、MUNIXCOM雖然我們沒有將Java對(duì)象作為COM對(duì)象暴露給平臺(tái)相關(guān)代碼,JNI與COM有二進(jìn)制兼容性。我們采用與COM一樣的跳轉(zhuǎn)表和調(diào)用約定。這意旦具有對(duì)COM,JNI就能成為Java虛擬COM我們認(rèn)為JNI不應(yīng)該是給定Java虛擬機(jī)所本地方法接口。標(biāo)準(zhǔn)口的好處在于程序員可臺(tái)相關(guān)代碼庫(kù)載到不同的Java虛擬機(jī)序員可層且與虛擬有關(guān)的接口來獲得較序員可層接口軟件組件。實(shí)際上,們希望隨著Java環(huán)境和組件軟件技術(shù)發(fā)展,本地方法將變得越來利用JNI編程本地方法程序設(shè)計(jì)人員應(yīng)開始利用JNI進(jìn)行編程。JNI編知條件,例如終端用戶可能正運(yùn)行的廠商的虛擬JNI標(biāo)本地庫(kù)能在給定Java虛擬最好保證。例如,雖
13、然JDK1.1將繼續(xù)支JDK1.0中所實(shí)現(xiàn)的舊式的JDK接口。依賴法將不得不重新編寫如果您正在實(shí)現(xiàn)Java虛擬機(jī),則應(yīng)該實(shí)現(xiàn)JNI。們JavaSoft獲許可方)盡力確保JNI不會(huì)占用虛擬機(jī)實(shí)現(xiàn)的系統(tǒng)開銷或施加任何限制,包括對(duì)我們可能忽視了的問題,請(qǐng)告知我們。JDK1.1.2中的變化為了更好地支持Java運(yùn)時(shí)環(huán)(JRE)JDK1.1.2中對(duì)調(diào)用API在幾面作了擴(kuò)展。這些變化沒碼JNI法接口也沒有改變JDK1_1InitArgs結(jié)構(gòu)中的reserved0域已被重新命名為version。JDK1_1InitArgs結(jié)構(gòu)保存JNI_CreateJavaVM的JNI_GetDefaultJavaVMIn
14、itArgs和JNI_CreateJavaVM的調(diào)用者必須設(shè)為0 x00010001JNI_GetDefaultJavaVMInitArgs為jint持所請(qǐng)求的版JDK1_1InitArgs結(jié)構(gòu)reserved1為properties。這NULL-終結(jié)數(shù)組。每個(gè)name=value表示系統(tǒng)屬性(該功能對(duì)應(yīng)Java中的-D選項(xiàng))。在JDK1.1.1中,調(diào)DestroyJavaVM線程必須是虛擬機(jī)中的唯一用戶線JDK1.1.2了這一調(diào)用DestroyJavaVM時(shí)有多個(gè)用戶線程,則虛擬機(jī)將等當(dāng)前線程成為唯一的用戶線程,然后銷毀自己-設(shè)計(jì)關(guān)。調(diào)著重討論JNI中的主要設(shè)計(jì)問題,其中的大部分問題API設(shè)
15、計(jì)5調(diào)API討論JNI針平臺(tái)相關(guān)代碼是通過調(diào)用JNI來訪問Java虛擬機(jī)功能JNI可通過接口指針來獲得。接口指針是指針的指針,它指向個(gè)指針數(shù)組,而指針數(shù)組中的每個(gè)元素又。每個(gè)接口函數(shù)都處數(shù)組的某個(gè)預(yù)定偏移圖2-1說指針的組織結(jié)圖2-1接口指針JNI接口的組織類似于C+虛擬函數(shù)表或COM接口。使用接口表編入的函數(shù)表的好處是使JNI名字空間與平臺(tái)相關(guān)代碼分開。虛擬地提供多個(gè)版本的JNI函數(shù)表。例如,虛擬機(jī)可支持以下兩個(gè)JNI一個(gè)表對(duì)非法參數(shù)進(jìn)行全面檢查,適用于調(diào)試程序;另一個(gè)表只進(jìn)行JNI規(guī)范所要求的最小程度的檢查,因此效率較高JNI接口指針只在當(dāng)線程中前線程中有效。因此,。實(shí)現(xiàn)JNI的虛擬機(jī)可將
16、本地線程能將接口指針從一的數(shù)據(jù)分配和儲(chǔ)存?zhèn)€線程傳JNI遞到指針JNI接口指針當(dāng)作參數(shù)來接受。虛擬機(jī)在從相同的Java線程中對(duì)本法進(jìn)多次調(diào)用時(shí),保證傳遞給該本地指針是相同的。但的Java線程所調(diào)用,JNI針。載和鏈對(duì)本地方法的加載通過System.loadLibrary方法實(shí)現(xiàn)。下例中,類關(guān)的本地庫(kù),在該本地庫(kù)中給f的定義packagepkg;classClsnativedoublef(inti,Strings);staticSystem.loadLibrary(pkg_Cls);System.loadLibrary的序員任意選取的庫(kù)名。系統(tǒng)按照標(biāo)準(zhǔn)的但與平臺(tái)有關(guān)的處理方法將該庫(kù)轉(zhuǎn)換為本地庫(kù)名。
17、例,Solaris系統(tǒng)將名稱pkg_Cls轉(zhuǎn)換為libpkg_Cls.soWin32系統(tǒng)將相同的名稱pkg_Cls轉(zhuǎn)換為pkg_Cls.dll程序員可用單個(gè)庫(kù)來存放任意數(shù)量的類所需的所有本地方法,只要這些類將加載的本庫(kù)清同的類加載器所單。提供者應(yīng)該加載。虛擬機(jī)在其盡量選擇能夠避免內(nèi)部為每個(gè)類加載器庫(kù)名保護(hù)其所如果底層操作系統(tǒng)不支持動(dòng)態(tài)鏈接,則必須事先法鏈接到擬機(jī)上。這種情況下,虛擬機(jī)實(shí)際上不需要加載庫(kù)即可System.loadLibrary調(diào)員還可調(diào)用JNI函數(shù)RegisterNatives()來注冊(cè)與類關(guān)聯(lián)態(tài)鏈時(shí)RegisterNativesO別動(dòng)態(tài)鏈接程序是根據(jù)項(xiàng)的名稱來解析各項(xiàng)前綴Jav
18、a_mangled全限定的類名下劃線(“_)”分隔符mangled方法名對(duì)于重載的本地方法,加上兩個(gè)下劃線(“_)_,”后跟mangled參數(shù)簽名擬機(jī)將為本地庫(kù)中的方法查找匹配的方法名。它首先查找短名(沒有參數(shù)簽然后再查找?guī)?shù)簽名的長(zhǎng)名稱。只有當(dāng)載時(shí)程序員才有必要使用長(zhǎng)名。但如果本地方,則不會(huì)有問題。因?yàn)榉荍ava庫(kù)不必用長(zhǎng)名來鏈g為個(gè)方法g不是本地本地庫(kù)中。classCls1intg(inti);nativeintg(doubled);我們采取簡(jiǎn)單的名字?jǐn)噥y方案,以保證所有的Unicode字符C函數(shù)名。我們用下劃線(“_類名中稱或類字打頭,我們用_0、.、_9來2-1表2-1Unicode
19、字符轉(zhuǎn)換轉(zhuǎn)義字符序列表示0XXXXUnicode字符XXXX。1字符“_”2簽名中的字符-3簽名中的字符API都要遵守給定平臺(tái)上的庫(kù)調(diào)用標(biāo)準(zhǔn)約使用C調(diào)用約定Win32統(tǒng)使用_stdcall。被轉(zhuǎn)換為轉(zhuǎn)義字符JNI接口指針是本地方法的第一個(gè)參靜態(tài)還是非靜態(tài)而有所不同。非數(shù)。其類型是靜態(tài)本地方Java類的JNIEnv態(tài)本地方法的第二個(gè)參數(shù)是對(duì)其的參數(shù)對(duì)應(yīng)于通常Java方法的方法調(diào)用利用調(diào)用3JNI類結(jié)將描述Java間的碼2-1說如何用C函數(shù)來實(shí)現(xiàn)本地f對(duì)UNIX統(tǒng)是對(duì)對(duì)象的引用回值將結(jié)果傳回類C類地方法f的聲明packagepkg;classClsnativedoublef(inti,String
20、s);長(zhǎng)mangled實(shí)現(xiàn)ti代碼示例2-1:用C實(shí)現(xiàn)本地方法jdoubleJava_pkg_Cls_f_ILjava_lang_String_*env,接口指/*針*/jobjectobj,/*“this”指針*/jinti,/*第一個(gè)參數(shù)*/jstrings)第/*二個(gè)參數(shù)*/*取得Ja字符串的版本*/constchar*str=(*env)-GetStringUTFChars(env,s/*處理該字符串*/*至此完成對(duì)str的處理*/*env)-ReleaseStringUTFChars(env,s,steturn意,我們總是用接口針env2-2Java對(duì)C+此代碼寫得稍簡(jiǎn)潔碼代碼示例2
21、-2:用C+實(shí)現(xiàn)本地方法externC指定/*C調(diào)用約定*/jdoubleJag_Cls_f_ILjava_Stv*env,接口指/*針*/jobjectobj,/*“this”指針*/jinti,/*第一個(gè)參數(shù)*/jstrins)第/*二個(gè)參數(shù)*/constchar*str=env-GetStringUTFChars(seleaseSths(s,stetC+與C的完全應(yīng)的C對(duì)應(yīng)代碼變得更為直接,樣C+JNI針C+定義為內(nèi)聯(lián)成員函數(shù),它們將擴(kuò)展為Java對(duì)基本類型(Java和平臺(tái)相關(guān)代碼之間直接進(jìn)行復(fù)制。而Java對(duì)象由引用來傳遞。虛擬機(jī)必須跟蹤傳到平臺(tái)相關(guān)代碼中對(duì)象,以使這些對(duì)象不會(huì)被垃圾收
22、集器釋放臺(tái)相關(guān)代碼必須能用某種虛擬機(jī)些對(duì)象,同時(shí),必須能夠移走臺(tái)相關(guān)代碼引用過的對(duì)JNI將平臺(tái)相關(guān)代碼使用的對(duì)象引用分成兩類:局部引用和法調(diào)用期間有法返回后被自動(dòng)釋放掉到被顯式釋放。對(duì)象是被作為局部引用傳遞給本地方JNI的所有Java對(duì)象也JNI許程序員從局部引用創(chuàng)建全局引用。Java對(duì)JNI函數(shù)既可接受全局引用也可接受局部引用。本地方法將局部引用或全局引用作為結(jié)果返回。大多數(shù)情況下,程序員應(yīng)該依靠虛擬機(jī)在本地方法返回后釋放所有局部引用。但是,有時(shí)程序員必須顯式釋放某個(gè)局部引用。例如,考慮以下的情形:本地方法要訪問一個(gè)大型Java對(duì)象,于是創(chuàng)建了對(duì)該Java對(duì)象的局部引用。然后,本地方法要在返
23、回調(diào)用程序之前執(zhí)行其它計(jì)算。對(duì)這個(gè)大型Java對(duì)象的局部引用將防止該對(duì)象被當(dāng)作垃圾收集,即使在剩余的運(yùn)算中并不再需要該對(duì)象。本地方法創(chuàng)建了大量的局部引用,但這些局部引用并不是要同時(shí)使用。由于虛擬機(jī)需要一定的空間來跟蹤每個(gè)局部引用,創(chuàng)建太多的局部引用將可能使系統(tǒng)耗盡內(nèi)存。例如,本地方法要在一個(gè)大型對(duì)象數(shù)組中循環(huán),把取回的元素作為局部引用,并在每次如,本地方法要在一個(gè)大型對(duì)象數(shù)組中循環(huán),把取回的元素作為局部引用,并在每次迭代時(shí)對(duì)一個(gè)元素進(jìn)行操作。每次迭代后,程序員不再需要對(duì)該數(shù)組元素的局部引用。JNI允許程序員在本地方法內(nèi)的任何地方對(duì)局部引用進(jìn)行手工刪除。為確保程序員可釋JNI將不能創(chuàng)建額外的局部
24、引用,除非是這些JNI為結(jié)引用僅在創(chuàng)建它們的線程中有效引用從一個(gè)線程傳遞一個(gè)線程中。實(shí)現(xiàn)局部引用為了實(shí)現(xiàn)局Java擬為每Java的控制轉(zhuǎn)換都創(chuàng)建了注冊(cè)服務(wù)程序。注冊(cè)服務(wù)程序?qū)⒉豢梢苿?dòng)的為Java對(duì)象,并防止這些對(duì)象被當(dāng)作垃圾收集。所有傳給本地Java對(duì)象括那些作為JNI函數(shù)調(diào)用結(jié)果返回的對(duì)象)將被自動(dòng)添加冊(cè)服務(wù)程服務(wù)程序?qū)⒈粍h除,其中的所有項(xiàng)都可可用各種不同的方法來實(shí)現(xiàn)注冊(cè)服務(wù)表鏈、接列表或hash表來實(shí)現(xiàn)。雖然用計(jì)數(shù)可用來避免注冊(cè)服務(wù)程復(fù)項(xiàng)JNI實(shí)現(xiàn)須檢測(cè)和消除重復(fù)的項(xiàng)。守方式掃描本地堆棧并不能如實(shí)地實(shí)現(xiàn)局平臺(tái)相關(guān)代碼可將局部引用儲(chǔ)存在全局或堆數(shù)據(jù)結(jié)構(gòu)中。訪問Java對(duì)JNI提供了一大批用來
25、訪問全局?jǐn)?shù)。這意味著無論虛擬機(jī)內(nèi)部如何表示Java對(duì)象,相同的本地方法實(shí)現(xiàn)都能工作。這就是為什么JNI被各種各樣的虛擬機(jī)實(shí)現(xiàn)所支持的關(guān)鍵原因。通過不透明的引用來使用訪問函數(shù)的開銷比直訪問C結(jié)開銷高。我們相信,大Java員用本地方法是為了完成一些務(wù),此時(shí)這種接口的開銷不是首要問題。訪問基本類型數(shù)組對(duì)于含數(shù)據(jù)類型(如整數(shù)數(shù)組和Java對(duì)象來說,這種開銷考慮一下用于執(zhí)行矢量和矩陣運(yùn)算的本地方法的情形便知)。對(duì)Java組進(jìn)行迭代過函數(shù)調(diào)用取回?cái)?shù)組的每個(gè)元素,決辦法是引入“釘住”地方法能夠要求虛擬機(jī)釘住數(shù)組內(nèi)容。而后,該本值元素的直接指針。但是,這種方垃圾收集器必須支持釘住。虛擬機(jī)必須在內(nèi)存中連續(xù)存放基
26、本類型數(shù)組。雖然大多數(shù)基本類型數(shù)組都是連續(xù)存放的,但布爾數(shù)組可以壓縮或不壓縮存儲(chǔ)。因此,依賴于布爾數(shù)組確切存儲(chǔ)方式的本地方法將是不可移植的。們將采取折衷方法來克服上述兩個(gè)問題。先,我們提供了Java數(shù)組的一部分和本地內(nèi)存緩沖之間復(fù)本類型數(shù)組元素。這些函數(shù)只有在本地方法只需訪問大型數(shù)組中的一小部分元時(shí)才使用。次,程序員可用另一套函數(shù)來取回?cái)?shù)組元素的受約束版本。記住,這些函數(shù)可求Java虛擬機(jī)分配存儲(chǔ)空間和進(jìn)行復(fù)制。虛擬機(jī)實(shí)現(xiàn)將決定這些函數(shù)是否真復(fù)制該數(shù)組,如如果垃圾收集器支持釘住,且數(shù)組的布局符合本地方法的要求,則不需要進(jìn)行復(fù)制。否則,該數(shù)組將被復(fù)制到不可移動(dòng)的內(nèi)存塊中(例如,復(fù)制到C堆中),并
27、進(jìn)行必要的格式轉(zhuǎn)換,然后返回指向該副本的指針。素。當(dāng)調(diào)用這些間進(jìn)行協(xié)調(diào)并將函數(shù)時(shí),系統(tǒng)或副本釋放。以通知虛擬機(jī)本釋放數(shù)組,者在原始數(shù)組需要訪問這些數(shù)組其不可移動(dòng)副本這種處理可對(duì)每個(gè)給數(shù)組分別作出復(fù)制或釘住的器可能復(fù)制小對(duì)象而釘住型對(duì)象。JNI實(shí)現(xiàn)須確保多個(gè)線程中運(yùn)可同時(shí)訪問組JNI以為每個(gè)被釘住的數(shù)組保留一個(gè)內(nèi)部計(jì)數(shù)器,以便某個(gè)線會(huì)解開同時(shí)被另一個(gè)線程釘組JNI必將基本類型數(shù)組鎖住以專供某個(gè)本地方法訪問。同時(shí)從的線程對(duì)Java數(shù)組進(jìn)行更新將導(dǎo)致不確結(jié)果。訪問JNI允許本地方法訪問Java對(duì)象的域或調(diào)用其方JNI類簽名來識(shí)別方法和域。從名稱和簽名來定域或?qū)ο蟮倪^程可分為兩步。例如,為調(diào)用類cls
28、中的f方法,平臺(tái)相關(guān)代碼首先要獲得IDjmethodIDmid=env-GetMethodID(cls,f,(ILjava/lang/String;)D);,平臺(tái)相關(guān)代碼可重復(fù)使用該方法ID而無須再查找該方法,如下所示:jdoubleresult=env-CallDoubleMethod(obj,mid,10,str);ID或方法ID并不能防止虛擬機(jī)卸載生成該ID的類。該類被卸載之后,該方ID或域ID亦變成無效。因此,如果平臺(tái)相關(guān)代碼要長(zhǎng)時(shí)間使用某個(gè)方法ID保留對(duì)所涉及類的活引用,或重新計(jì)算該方法ID或域IDJNI對(duì)IDID實(shí)現(xiàn)報(bào)告編程錯(cuò)誤JNI不檢查諸如傳遞NULL指針或非法參數(shù)類型類的編程
29、錯(cuò)誤。非法的參數(shù)類型包括諸如要Java類對(duì)象時(shí)卻用了普通Java對(duì)象、-r這樣錯(cuò)誤JNI不檢查這些編程錯(cuò)誤的強(qiáng)迫JNI函數(shù)去檢查所有可能的錯(cuò)誤情況將降低正常(正確)的本地方法的性能在許多情況下,沒有足夠的運(yùn)行時(shí)的類型信息可供這種檢查使用。大多數(shù)C庫(kù)函數(shù)對(duì)編程錯(cuò)誤不進(jìn)行防范。例如,printf()函地址時(shí)通常是引起運(yùn)行錯(cuò)而不是返回錯(cuò)誤代碼。強(qiáng)迫C庫(kù)函數(shù)檢查所有可能的錯(cuò)誤情況將有可能引起這種檢查被重復(fù)進(jìn)行-先是在用戶代碼進(jìn)行,然又在庫(kù)函數(shù)中再次進(jìn)行員不得將非法指針或錯(cuò)誤類型的參數(shù)傳遞給JNI函數(shù)。否則,可能產(chǎn)包括可能使系統(tǒng)狀態(tài)受損或使虛擬機(jī)崩潰。JavaJNI允許Java處理突出的Java處理的J
30、ava傳回虛擬常和錯(cuò)誤代碼JNI函數(shù)使用Java來報(bào)告錯(cuò)誤情況。大多數(shù)情況JNI過返回錯(cuò)誤代碼并拋Java來報(bào)告錯(cuò)誤情況。錯(cuò)誤代碼通常值(NULL這種特殊的返回值在返回值范圍之外。因此,程序員快速檢查上一個(gè)JNI調(diào)用所返回的值以確定是否出錯(cuò),并通過調(diào)用函數(shù)ExceptionOccurred()來獲得異常對(duì)象,它含有對(duì)錯(cuò)誤情況的更詳細(xì)說明。下兩種情況中,程序員需要先查出異常,然后才能檢查錯(cuò)誤代碼:調(diào)用Java方法的JNI函數(shù)返回該Java方法的結(jié)果。程序員必須調(diào)用ExceptionOccurred()以檢查在執(zhí)行Java方法期間可能發(fā)生的異常。某些用于訪問JNI數(shù)組的函數(shù)并不返回錯(cuò)誤代碼,但可能
31、會(huì)拋出ArrayIndexOutOfBoundsException或ArrayStoreException。值如果不是錯(cuò)誤代碼值線程的情況影響當(dāng)前線線程以外的其它線程可能會(huì)拋出異步相關(guān)代碼的執(zhí)行,直到出現(xiàn)下列情況該平臺(tái)相關(guān)代碼調(diào)用某個(gè)有可能拋出同步異常的JNI函數(shù),或者該平臺(tái)相關(guān)代碼用ExceptionOccurred()顯式檢查同步異?;虍惒疆惓W⒁?,只有那些有可能拋出同步異常的JNI函數(shù)才檢查異步異常。本地方法應(yīng)在必要的地方(例如,它異常檢查的緊密循環(huán)ExceptionOccurred()檢查以確保當(dāng)前線程可在適當(dāng)時(shí)間內(nèi)對(duì)異步異應(yīng)。的處理種方法來處理平臺(tái)相關(guān)代碼本地方法可選擇立即返回,使異
32、常在啟動(dòng)該本地方法調(diào)用的Java代碼中拋出。平臺(tái)相關(guān)代碼可通過調(diào)用ExceptionClear()來清除異常,然后執(zhí)行自己的異常處理代碼。JNI關(guān)代碼必須先以下這些JNIIDIDIDID為義調(diào)試-JNI的類型和數(shù)據(jù)結(jié)討論JNI如何將Java類型映射到本地C類3TJava類計(jì)關(guān)類表3-1基本類型和本地等效類型Java類型本地類型說明booleanjboolean無符號(hào),8位bytejbyte無符號(hào),8位charjchar無符號(hào),16位shortjshort有符號(hào),16位intjint有符號(hào),32位longjlong有符號(hào),64位floatjfloat32位doublejdouble64位void
33、voidN/A、丄/.jsize整數(shù)類型用于描述主typedefjintjsize;IDIDIDID為義IDIDIDID為義JNI對(duì)應(yīng)Java類JNI組織層IDIDIDID為義圖3-1IDIDIDID為義IDIDIDID為義jobieirt尸尸有Java;ic1assjs11iflqjattayjobj已匚七Attayjboq1已呂nArrayjbyt已AtEmyjchatAttayjshortArtayjintArtayjlodqAttsyj1oat.Artayjdoub1已衛(wèi)!工Ttayjthrowabl已JNIjamlan月.das號(hào)応敷;java.Ian月.Strin月對(duì)敏;(數(shù)組to
34、bject黑魚Fl;fbooleanfit組CbyteftSa)晶r迪綃:shortfill組tintftifi)血n月教組IflORt數(shù)組dou血數(shù)組;jaiTLlaTL月.Thrciivaljle對(duì)象;3-1引用類型層次義為與jobject一樣IDIDIDID為義IDIDIDID為義typedefjobjectjclass;C+JNI類關(guān)IDIDIDID為義IDIDIDID為義class_jobject;class_jclass:public_jobject;typedef_jobject*jobject;typedef_jclass*jclass;為義IDID規(guī)的C指針類不透明結(jié)構(gòu)域不透
35、明結(jié)構(gòu)方法為義為義值類聯(lián)類組單類類型簽JNIJava擬類簽3-2這類簽表3-2Java虛擬機(jī)類型簽名類型簽名Java類型Zbooleanbyte值為(x&0 x1f)6)+(y&0 x3f)節(jié)值為(x&0 x1f)6)+(y&0 x3f)節(jié)為義CcharSshortIintJlongFfloatDdoubleLfully-qualified-class;全限定的類typetype(arg-types)ret-type方法類型,Java方法:longf(intn,Strings,intarr);以下類型簽名:(ILjava/lang/String;I)JUTF-8值為(x&0 x1f)6)+(y
36、&0 x3f)節(jié)值為(x&0 x1f)6)+(y&0 x3f)節(jié)為義值為(x&0 x1f)6)+(y&0 x3f)節(jié)值為(x&0 x1f)6)+(y&0 x3f)節(jié)為義JNI用UTF-8字符串來表示各種字符類UTF-8樣UTF-8符串的編碼方僅ASCII夠按每字符一個(gè)字節(jié)表16u007F范圍內(nèi)的字符都用單字節(jié)表示00-6位節(jié)的值???u000)xyJava虛擬機(jī)所u0001u0080uO7FF1106-10位圍內(nèi)的字符用一對(duì)字節(jié)10位為義x,yu0800到uFFFF范圍為義為義|d|l215位7:|110S-11位為義為義值為(x&0 xf)12)+(y&0 x3f)類型必須為void(V)。
37、clazz參數(shù)務(wù)必不要引組類NewObject編程人員應(yīng)將傳遞給構(gòu)數(shù)緊跟著放在methodIDNewObject()收到這些們傳給編程人員所要調(diào)用的Java方法。NewObjectA編程人員應(yīng)將傳遞給構(gòu)造函數(shù)的所有參數(shù)放在jvalues類型的數(shù)組args中,該數(shù)組緊跟著放在methodID參數(shù)NewObjectO組這將把它們傳給編程人員所要調(diào)用Java為義NewObjectVva_list類NewObject()收到這args該后,將把它們編程人員應(yīng)將傳遞給構(gòu)造函數(shù)的參數(shù)緊跟著放在methodID參數(shù)傳給編程人員所要調(diào)用的Java參數(shù):env:JNI接口指針。clazz:Java類對(duì)象。met
38、hodIDIDNewObject的其它參數(shù):傳給構(gòu)造函數(shù)的參數(shù)。NewObjectA的其它參數(shù):args傳給組NewObjectV的其它參數(shù):args傳給va_list返回值:返回Java對(duì)象,如果無法構(gòu)造該對(duì)象,則返回NULL拋出:InstantiationException該類為類OutOfMemoryError為義GetObjectClass返回對(duì)象的類。參數(shù):env:JNI接口指針ob:Jjava對(duì)象(不返回值:返回Java類對(duì)象IsInstanceOf類的實(shí)測(cè)試對(duì)象是否為某參數(shù):env:JNI接口指針ob:Jjava對(duì)象。cla:Jzazva類對(duì)象返回值:可將強(qiáng)轉(zhuǎn)換為對(duì)象可強(qiáng)制轉(zhuǎn)換為
39、任何類。GetFieldID()類GetFieldID()類為義IsSameObjectjbooleanIsSameObject(JNIEnv*env,jobjectref1,jobjectref2);測(cè)試兩個(gè)引用是否引用同一Java對(duì)象。參數(shù):env:JNI接口指針。ref1:Java對(duì)象。ref2:Java對(duì)象。返回值:reflref2Java對(duì)為NULL則JNI_TRUE則回JNI_FALSE。訪問對(duì)GetFieldIDjfieldIDGetFieldID(JNIEnv*env,jclassclazzconstchar*name,constchar*sig);類實(shí)態(tài)ID該簽名指定。訪問G
40、etFieldID()類GetFieldID()類為義GetFieldSetFieldID檢對(duì)GetFieldID()獲取數(shù)組的長(zhǎng)應(yīng)使用GetArrayLength()GetFieldID()獲取數(shù)組的長(zhǎng)應(yīng)使用GetArrayLength()為義參數(shù):env:JNI接口指針。clazz:Java類對(duì)象。name:0終結(jié)的UTF-8字符串中的域名。sig:0終結(jié)的UTF-8字符串中的域簽名。返回值:ID敗則NULL拋出:NoSuchFieldErrorExceptionlnlnitializerError導(dǎo)類敗OutOfMemoryError統(tǒng)GettypeFieldNativeTypeGetF
41、ield(JNlEnv*env,jobjectobjjfieldlDfieldlD);該訪問對(duì)象的實(shí)態(tài))域的值。要訪問過調(diào)GetFieldID()獲取數(shù)組的長(zhǎng)應(yīng)使用GetArrayLength()GetFieldID()獲取數(shù)組的長(zhǎng)應(yīng)使用GetArrayLength()為義結(jié)類應(yīng)GettypeFieldtype實(shí)際NativeType換GetFieldlD()而得到的域ID下表說明了GetField替換為域的Java類型(或?yàn)樵摾虒?duì)應(yīng)的本地類型。為義表4-1GetField訪問器例程系列GetField例程名本地類型GetObjectField()jobjectGetBooleanField
42、()jbooleanGetByteField()jbyteGetCharField()jcharGetShortField()jshortGetIntField()jintGetLongField()jlongGetFloatField()jfloatGetDoubleField()jdouble參數(shù):env:JNI接口指針。obj:Java對(duì)象(不能為NULLfieldIDID返回值:SettypeFieldvoidSetField(JNIEnv*env,jobjectobj,jfieldIDfieldID,NativeTypevalue);ID該訪問器例程系列設(shè)置對(duì)象的實(shí)例(非靜態(tài))域的值
43、。要訪問的域由通過調(diào)SetFieldID()為義說SetField結(jié)類應(yīng)SetFieldtype換為Java類實(shí)際NativeType換為該例程對(duì)應(yīng)的本地類型。表4-2SetField訪問器例程系列SetField例程名本地類型SetObjectField()jobjectSetBooleanField()jbooleanSetByteField()jbyteSetCharField()jcharSetShortField()jshortSetIntField()jintSetLongField()jlongSetFloatField()jfloatSetDoubleField()jdoubl
44、e參數(shù):env:JNI接口指針。obj:Java對(duì)象(不為NULLfieldIDID。value值調(diào)用實(shí)GetMethodID為義jmethodIDGetMethodID(JNIEnv*env,jclassclazzconstchar*name,constchar*sig);類實(shí)態(tài)IDclazz類義為義clazz繼該簽GetMethodID()ID應(yīng)init為時(shí)void(V)為參數(shù):env:JNI接口指針。clazz:Java類對(duì)象。name:0終結(jié)的UTF-8字符串中的方法名。sig:0終結(jié)的UTF-8字符串中的方法簽名返回值:ID則為NULL拋出:NoSuchMethodErrorExce
45、ptionlnlnitializerError導(dǎo)類OutOfMemoryErrorCallMethod例CallMethodA例CallMethodV例NativeTypeCallMethod(NativeTypeCallMethodA(NativeTypeCallMethodV(這三個(gè)調(diào)Java實(shí)。它們的差別僅在于向所調(diào)用的方法傳遞參數(shù)時(shí)所用的這三個(gè)ID調(diào)用Java對(duì)象的實(shí)例(非靜態(tài))方法。須過調(diào)獲當(dāng)這些函數(shù)用于調(diào)用私時(shí)ID須實(shí)類而不應(yīng)從其某個(gè)超類派生CallMethod例程編程人員應(yīng)將要傳給方緊CallMethod接受這些參數(shù)并將其傳給編程人員所要調(diào)JavaCallMethodA例程編程人
46、員應(yīng)將要傳給方法的所有參數(shù)放在緊跟在類型數(shù)組argsCallMethodAroutine受這些數(shù)組中的參并將其傳給編程人員所要調(diào)用的Java方法。為義CallMethodV例程編程人員緊跟著在methodIDva_list類變CallMethodVroutine這傳給編程人員調(diào)Java結(jié)果類型說調(diào)用例程。用戶應(yīng)將CallMethodtype替換為所調(diào)用方法的Java類同時(shí)為義NativeType換為該表4-3實(shí)例方法調(diào)用例程CallMethod例程名本地類型為義為義voidCallVoidMethod()CallVoidMethodA()CallVoidMethodV()CallObjectM
47、ethod()CallObjectMethodA()CallObjectMethodV()jobjectCallBooleanMethod()CallBooleanMethodA()CallBooleanMethodV()CallByteMethod()CallByteMethodA()CallByteMethodV()jbyteCallCharMethod()CallCharMethodA()CallCharMethodV()jcharCallShortMethod()CallShortMethodA()CallShortMethodV()jshortCallIntMethod()CallI
48、ntMethodA()CallIntMethodV()jintCallLongMethod()CallLongMethodA()CallLongMethodV()jlongCallFloatMethod()CallFloatMethodA()CallFloatMethodV()jfloatCallDoubleMethod()CallDoubleMethodA()CallDoubleMethodV()jdouble參數(shù):env:JNI接口指針obj:Java對(duì)象。methodIDIDCallMethod例程的其它參數(shù):傳給JavaCallMethodA例程的其它參數(shù):組CallMethodV例程
49、的其它參數(shù):va_list返回值:調(diào)Java結(jié)拋出:執(zhí)行Java方法時(shí)拋出的異常。CallNonvirtualMethod例程CallNonvirtualMethodA例程CallNonvirtualMethodV例程N(yùn)ativeTypeCallNonvirtualMetho(dJNIEnv*env,jobjNativeTypeCallNonvirtualMethod(AJNIEnv*env,jobNativeTypeCallNonvirtualMethod(VJNIEnv*env,job這些操作根據(jù)指定的類和方法ID調(diào)用某Java對(duì)象的實(shí)例(非靜態(tài))方法。參須過調(diào)類的獲CallNonvirt
50、ualMethodCallMethodCallMethod對(duì)類調(diào)CallNonvirtualMethod為義則根據(jù)獲真實(shí)類或IDclazz類獲類調(diào)ID須對(duì)CallNonvirtualMethod例程編程人員應(yīng)將要傳給緊methodIDCallNonvirtualMethodroutine接受這傳給編程人員所要調(diào)JavaCallNonvirtualMethodA例程編程人員應(yīng)將要傳給緊跟在methodIDjvalues類型數(shù)組argsCallNonvirtualMethodAroutine這些數(shù)組傳給編程人員所要調(diào)用的Java編程人員應(yīng)將要傳給方法的所有參數(shù)放在緊跟在methodID參數(shù)之后的v
51、a_list類型數(shù)argsCallNonvirtualMethodVToutine這將其傳給編程人員所要調(diào)用的JavaCallNonvirtualMethodV例程調(diào)用例程。用戶應(yīng)下表根據(jù)結(jié)果類型說明了各CallNonvirtualMethod表中的實(shí)際方法調(diào)用例程名type替換為所調(diào)用方法的Java類時(shí)NativeType換為該應(yīng)表4-4CallNonvirtualMethod例程CallNonvirtualMethod例程名本地類型CallNonvirtualVoidMethod()CallNonvirtualVoidMethodA()CallNonvirtualVoidMethodV()
52、CallNonvirtualObjectMethod()CallNonvirtualObjectMethodA()CallNonvirtualObjectMethodV()CallNonvirtualBooleanMethod()CallNonvirtualBooleanMethodA()jboolean為義jbytejcharjshortjintjlongjfloatjdouble參數(shù):env:JNI接口指針。cla:zJzava類。ob:jJava對(duì)象。IDCallNonvirtualMethod例程的其它參數(shù):傳給JavaCallNonvirtualMethodA例程的其它參數(shù):組Cal
53、lNonvirtualMethodV例程的其它參數(shù):ID態(tài)域,則為NULLID態(tài)域,則為NULL為義簽GetStaticFieldID檢態(tài)類初始化。靜態(tài)簽名返回值:調(diào)用Java方法的結(jié)果拋出:執(zhí)行Java方法時(shí)訪問靜態(tài)GetStaticFieldIDjfieldIDGetStaticFieldID(JNIEnv*env,jclassclazzconstchar*name,constchar*sig);返回類的靜態(tài)域的域ID。SetStaticField訪問GetStaticFieldID()將未參數(shù):env:JNI接口指針。clazz:Java類對(duì)象。name:0終結(jié)的UTF-8sig:0終結(jié)
54、的UTF-8字符返回值:拋出:拋出:為義導(dǎo)致類初始化程序失敗NoSuchFieldErrorExceptionInInitializerErrorOutOfMemoryError統(tǒng)GetStaticFieldNativeTypeGetStaticField(JNIEnv*env,jclassclazzjfieldIDfieldID);過調(diào)該訪問器例程系列返回對(duì)象的靜態(tài)域的值。要訪問GetStaticFieldID()而得到的域ID指定。拋出:拋出:為義拋出:拋出:為義說明了GetStaticField中的type替換為域的Java類NativeType換為該對(duì)應(yīng)結(jié)果類型。應(yīng)將GetStatic
55、Field表中的某個(gè)實(shí)際例程名),然后將拋出:拋出:為義拋出:拋出:為義表4-5GetStaticField訪問器例程系列GetStaticField例程名本地類型GetStaticObjectField()jobjectGetStaticBooleanField()jbooleanGetStaticByteField()jbyteGetStaticCharField()jcharGetStaticShortField()jshortGetStaticIntField()jintGetStaticLongField()jlongGetStaticFloatField()jfloat為義jdou
56、bleGetStaticDoubleField()參數(shù):env:JNI接口指針。clazz:Java類對(duì)象。fieldID態(tài)ID返回值:態(tài)SetStaticField例程voidSetStaticFiel(dJNIEnv*env,jclassclazz,jfieldIDfieldID,NativeTypevalue);該訪問器例程系列設(shè)置對(duì)象的靜態(tài)域的值。要訪問的域由通過調(diào)用GetStaticFieldID()而得到的域ID指定。說SetStaticField結(jié)類應(yīng)SetStaticField中的type替換為域的Java類型(或使用表中的某個(gè)實(shí)際例程名),然后將NativeType換為該對(duì)應(yīng)
57、類表4-6SetStaticField訪問器例程系列SetStaticField例程名本地類型SetStaticObjectField()jobjectSetStaticBooleanField()jbooleanSetStaticByteField()jbyteSetStaticCharField()jcharSetStaticShortField()jshortSetStaticIntField()jintSetStaticLongField()jlongjfloatjdoubleSetStaticFloatField()SetStaticDoubleField()參數(shù):env:JNI接口
58、指針。clazz:Java類對(duì)象。fieldID態(tài)IDvalue值調(diào)用靜態(tài)方法GetStaticMethodIDjmethodIDGetStaticMethodID(JNIEnv*env,jclassclazzconstchar*name,constchar*sig);返回類的靜態(tài)方法的方法ID。方法由其名稱和簽名指定。GetStaticMethodID()將未初始化的類初始化。參數(shù):env:JNI接口指針clazz:Java類對(duì)象name:0終結(jié)UTF-8字符串中靜態(tài)方法名。sig:0終結(jié)UTF-8字符串中的方法簽名。返回值:返回值:ID必須從clazz類ID必須從clazz類為義ID敗則為
59、NULL拋出:TOC o 1-5 h z HYPERLINK l bookmark178NoSuchMethodError態(tài) HYPERLINK l bookmark180ExceptionlnlnitializerError導(dǎo)類敗 HYPERLINK l bookmark182OutOfMemoryError統(tǒng)CallStaticMethod例程CallStaticMethodA例程CallStaticMethodV例程N(yùn)ativeTypeCallStaticMetho(dJNlEnv*env,jclassclazz,jmethodlDmethodlD,.);NativeTypeCallSt
60、aticMethodA(JNlEnv*env,jclassclazz,jmethodlDmethodlD,jvalue*args);NativeTypeCallStaticMethodV(JNlEnv*env,jclassclazz,jmethodlDmethodlD,va_listargs);這ID調(diào)Java對(duì)態(tài)methodID須通過調(diào)用GetStaticMethodlD()得到。為義CallStaticMethod例程編程人員應(yīng)將要傳給緊跟著放在methodID為義傳給編程人員所要調(diào)CallStaticMethodroutine接受這表4-7CallStaticMethod調(diào)用例程Call
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 2024花木租賃合同范例
- 2024工廠設(shè)備維修合同
- 2024注冊(cè)會(huì)計(jì)師《經(jīng)濟(jì)法》要點(diǎn)建設(shè)工程合同
- Sorbic-acid-Standard-生命科學(xué)試劑-MCE
- 立體農(nóng)場(chǎng)建設(shè)項(xiàng)目可行性報(bào)告
- 四年級(jí)數(shù)學(xué)(三位數(shù)乘兩位數(shù))計(jì)算題專項(xiàng)練習(xí)及答案
- 廣東省肇慶第四中學(xué)2024屆高三年級(jí)數(shù)學(xué)試題期末試題
- 禽蛋類買賣合同書(3篇)
- 師德教育心得體會(huì)
- 電白縣那霍衛(wèi)生院醫(yī)務(wù)人員醫(yī)德醫(yī)風(fēng)考評(píng)制度實(shí)施方案
- 中醫(yī)養(yǎng)生中醫(yī)養(yǎng)生與體質(zhì)調(diào)護(hù)課件
- 面試業(yè)務(wù)員問題及答案
- 戰(zhàn)略性領(lǐng)導(dǎo)力素質(zhì)模型字典
- 會(huì)議安全應(yīng)急處置保障方案
- 《麻雀》(全國(guó)一等獎(jiǎng))
- 初中音樂-《山東民歌》教學(xué)課件設(shè)計(jì)
- 豐田車系卡羅拉(雙擎)轎車用戶使用手冊(cè)【含書簽】
- 眾興實(shí)驗(yàn)小學(xué)教育教學(xué)視導(dǎo)工作匯報(bào)
- 潔凈區(qū)人員行為規(guī)范要求
- 2023年云南省7月普通高中學(xué)業(yè)水平考試物理試卷新版
- 2022屆高三語文一輪復(fù)習(xí)積累:現(xiàn)代漢語語法基礎(chǔ)知識(shí)
評(píng)論
0/150
提交評(píng)論