Java жергілікті интерфейсі - Java Native Interface

Жылы бағдарламалық жасақтама, Java жергілікті интерфейсі (JNI) Бұл шетелдік функция интерфейсі бағдарламалау жақтау бұл мүмкіндік береді Java а-да жұмыс істейтін код Java виртуалды машинасы (JVM) қоңырау шалу және шақыру[1] жергілікті қосымшалар (аппараттық құралдарға арналған бағдарламалар және операциялық жүйе платформа) және кітапханалар сияқты басқа тілдерде жазылған C, C ++ және құрастыру.

Міндеттері

JNI бағдарламашыны Java бағдарламалау тілінде толығымен жазуға болмайтын жағдайларды шешуге арналған жергілікті әдістерді жазуға мүмкіндік береді, мысалы. стандартты Java болған кезде сынып кітапхана платформаға арналған мүмкіндіктерді немесе бағдарлама кітапханасын қолдамайды. Ол қолданыстағы қосымшаны (басқа бағдарламалау тілінде жазылған) Java қосымшаларына қол жетімді етіп өзгерту үшін қолданылады. Стандартты кітапханалық сыныптардың көпшілігі JNI-ге әзірлеуші ​​мен пайдаланушыға функционалдылықты қамтамасыз етуге байланысты, мысалы. файл енгізу-шығару және дыбыстық мүмкіндіктері. Стандартты кітапханада өнімділікке және платформаға сезімтал API ендірулерін қосқанда барлық Java қосымшалары бұл функционалдыға қауіпсіз және платформадан тәуелсіз түрде қол жеткізуге мүмкіндік береді.

JNI жақтауы жергілікті әдіске Java қолдануға мүмкіндік береді нысандар Java коды осы объектілерді қолданатын сияқты. Жергілікті әдіс Java нысандарын құра алады, содан кейін оларды тексеріп, өз міндеттерін орындау үшін қолдана алады. Нәтижелі әдіс Java қосымшасының кодымен жасалған объектілерді тексеріп, қолдана алады.

JNI-ге тек қосымшалар мен қол қойылған апплеттер ғана жүгіне алады.

JNI-ге сүйенетін қосымша Java ұсынатын платформаның портативтілігін жоғалтады (ішінара шешім - бұл әр платформа үшін JNI кодының бөлек орындалуын жазу және Java операциялық жүйені анықтап, дұрысын жұмыс кезінде жүктеу).

Жергілікті кодты интерфейс Java-мен байланыстырып қана қоймай, ол Java-ны қолдана алады Кенеп, бұл мүмкін Java AWT жергілікті интерфейсі. Процесс шамамен бірнеше өзгертулермен бірдей. Java AWT жергілікті интерфейсі тек содан бері қол жетімді J2SE 1.3.

JNI сонымен қатар тікелей қол жеткізуге мүмкіндік береді құрастыру коды, тіпті а C көпір.[2] Java қосымшаларына құрастырудан қол жеткізуге болады.[3]

Дизайн

JNI шеңберінде жергілікті функциялар бөлек .c немесе .cpp файлдарында жүзеге асырылады. (C ++ JNI көмегімен сәл қарапайым интерфейсті ұсынады.) JVM функцияны шақырған кезде, ол JNIEnv көрсеткіш, а жұмыс тақырыбы нұсқаушы және Java әдісімен жарияланған кез-келген Java аргументтері. Мысалы, төмендегілер Java жолын жергілікті жолға түрлендіреді:

экстерн «С»JNIEXPORT жарамсыз JNICALL Java_ClassName_MethodName  (JNIEnv *env, жұмыс тақырыбы obj, jstring javaString){    const char *nativeString = env->GetStringUTFChars(javaString, 0);    // nativeString көмегімен бірдеңе жасаңыз    env->ReleaseStringUTFChars(javaString, nativeString);}

The env көрсеткіш - бұл JVM интерфейсін қамтитын құрылым. Ол JVM-мен өзара әрекеттесу және Java объектілерімен жұмыс істеу үшін қажетті барлық функцияларды қамтиды. Мысалы, JNI функциялары - жергілікті массивтерді Java массивтеріне түрлендіру, жергілікті жолдарды Java жолдарына айналдыру / айналдыру, нысандарды құру, ерекшеліктерді тастау және т.с.с. негізінен Java коды жасай алатын кез-келген нәрсені қолдануға болады. JNIEnv, айтарлықтай аз болса да.

Дәлел obj бұл жергілікті әдіс жарияланған Java нысанына сілтеме.

Жергілікті деректер түрлері Java деректер түрлерімен / олармен салыстыруға болады. Заттар сияқты күрделі түрлер үшін, массивтер және жіптер жергілікті код деректерді шақыру арқылы нақты түрлендіруі керек JNIEnv.

JNI орта көрсеткіші (JNIEnv *) түпнұсқа әдіс шеңберінде JNI ортамен өзара әрекеттесуге мүмкіндік беретін Java әдісімен салыстырылған әрбір жергілікті функция үшін аргумент ретінде беріледі. Бұл JNI интерфейсінің нұсқағышын сақтауға болады, бірақ ол тек ағымдық тізбекте жарамды болып қалады. Басқа ағындар алдымен қоңырау шалуы керек AttachCurrentThread () өздерін VM-ге қосып, JNI интерфейсінің көрсеткішін алу үшін. Қосылғаннан кейін, жергілікті ағын жергілікті әдіс аясында жұмыс істейтін қарапайым Java ағыны сияқты жұмыс істейді. Жергілікті жіп VM-ге ол шақырылғанға дейін жалғасады DetachCurrentThread () өзін ажырату.[4]

JNI құрылымы JVM емес жад ресурстарына автоматты түрде қоқыстарды жинауды қамтамасыз етпейді. Демек, жергілікті код (мысалы, ассемблер тілі) жергілікті код алатын барлық жад ресурстарын нақты шығару үшін жауапкершілікті өз мойнына алады.

Linux және Solaris платформаларында, егер жергілікті код өзін сигнал өңдеуші ретінде тіркесе, ол JVM үшін арналған сигналдарды ұстап қалуы мүмкін. A жауапкершілік тізбегі жергілікті кодтың JVM-мен өзара әрекеттесуін жақсарту үшін пайдалануға болады. Windows платформаларында, Құрылымдық ерекшелікті өңдеу (SEH) машинада (CPU / FPU) жасалған бағдарламалық жасақтаманың үзілістерін (мысалы, NULL сілтегішіне қол жеткізуді бұзу және нөлге бөлу операциялары сияқты) түсіру үшін жергілікті кодты SEH тырысу / ұстау блоктарына орау үшін және осы жағдайларды үзіліске дейін өңдеу үшін қолданылуы мүмкін. резервтік JVM-ге таратылады (яғни Java жағындағы код), мүмкін, өңделмеген ерекшелікке әкеледі.[өзіндік зерттеу? ]

NewStringUTF, GetStringUTFLength, GetStringUTFChars, ReleaseStringUTFChars және GetStringUTFRegion функциялары үшін қолданылатын кодтау «өзгертілген UTF-8»,[5] бұл UTF-8 барлық кірістер үшін жарамсыз, бірақ шынымен басқа кодтау. Нөлдік таңба (U + 0000) және кодтық нүктелер жоқ Негізгі көп тілді жазықтық (U + 10000-ден үлкен немесе тең, яғни суррогат жұптары UTF-16-да) модификацияланған UTF-8-де әр түрлі кодталған. Көптеген бағдарламалар бұл функцияларды дұрыс қолданбайды және функцияларға қайтарылған немесе берілген UTF-8 жолдарын өзгертілген UTF-8 жолдарының орнына стандартты UTF-8 жолдары ретінде қарастырады. Бағдарламалар NewTring, GetStringLength, GetStringChars, ReleaseStringChars, GetStringRegion, GetStringCritical және ReleaseStringCritical функцияларын қолдануы керек, олар UTF-16LE кодтауды кіші-ениан архитектураларында, ал UTF-16BE - үлкен ендиан архитектураларында, содан кейін UTF-16-ны қолданады. 8 конверсияның күнделікті тәртібі.[өзіндік зерттеу? ]

Картаға түсіру түрлері

Келесі кестеде Java (JNI) мен жергілікті код арасындағы типтердің салыстырылуы көрсетілген.

C түріJava тілінің түріСипаттамаҚолтаңба теріңіз
unsigned charjbooleanқол қойылмаған 8 битЗ
қол қойылған charджайт8 битке қол қойдыB
қолсыз қысқаjcharқол қойылмаған 16 битC
қысқаjshort16 битке қол қойдыS
ұзақаққұба32 битке қол қойдыМен

ұзақ ұзақ
__int64

жонгл64 битке қол қойдыДж
жүзуjfloat32 битF
екі есеjuble64 битД.
жарамсызV

Сонымен қатар, қолтаңба «L толық білікті сынып;» осы атаумен ерекше көрсетілген класты білдіретін болады; мысалы, қолтаңба «Ljava / lang / String;» сыныпқа қатысты java.lang.String. Сонымен қатар, префикс [ қолтаңбаға сол типтегі жиым жасайды; Мысалға, [I int массив типін білдіреді. Ақырында, а жарамсыз қолтаңбасы V код.

Бұл түрлер бір-бірін алмастырады. Біреуі қолдана алады аққұба әдетте сіз int, және керісінше, жоқ типтеу қажет. Алайда, Java жолдары мен массивтер арасында жергілікті жолдар мен массивтер арасында карта жасау әр түрлі. Егер а jstring a жерде қолданылады char * код JVM-ді бұзуы мүмкін.[өзіндік зерттеу? ]

Өнімділік

JNI белгілі бір жағдайларда айтарлықтай шығындар мен шығындарға ұшырайды:[6]

  • JNI әдістеріне функционалдық қоңыраулар, әсіресе әдісті қайта-қайта шақырған кезде қымбат.
  • Жергілікті әдістер JVM сызбасында көрсетілмеген және болуы да мүмкін емес JIT құрастырылған, әдіс қазірдің өзінде жинақталғандықтан.
  • Java массивін жергілікті кодқа қол жеткізу үшін көшіруге болады, ал кейінірек оны көшіруге болады. Массивтің өлшемі бойынша сызықтық болуы мүмкін.
  • Егер әдіс объектіні жіберсе немесе кері қоңырау шалуды қажет етсе, онда жергілікті әдіс JVM-ге өз қоңырауларын жасайды. Жергілікті кодтан Java өрістеріне, әдістеріне және түрлеріне қол жеткізу ұқсас нәрсені қажет етеді шағылысу. Қолтаңбалар жолдарда көрсетілген және JVM-ден сұралған. Бұл әрі баяу, әрі қате.
  • Java Strings - бұл объектілер, ұзындығы бар және кодталған. Жолға қол жеткізу немесе құру үшін O (n) көшірмесі қажет болуы мүмкін.

Балама нұсқалар

Microsoft виртуалды машинасын (Microsoft виртуалды машинасын) енгізу (Visual J ++ ) Java-дан жергілікті кодты шақырудың ұқсас механизмі болған, деп аталады Шикі интерфейс (RNI). Сонымен қатар, Java-ны білмейтін жергілікті кодты шақырудың оңай әдісі болды, мысалы, Windows API сияқты (бірақ онымен шектелмей). J / Direct. Алайда, келесі Sun - Microsoft сот ісі осы іске асыру туралы, Visual J ++ бұдан былай күтілмейді.

RNI пайдалану үшін JNI-ге қарағанда аз епті болды, өйткені Java ортасы көрсеткішімен бухгалтерлік есеп жүргізу қажет емес еді. Оның орнына барлық Java нысандарына тікелей қол жеткізуге болады. Мұны жеңілдету үшін Java сыныптарынан тақырыптық файлдар жасайтын құрал қолданылды. Сол сияқты, J / Direct-ті пайдалану қазіргі аралықтағы қажетті жергілікті кітапхана мен JNI-ге қарағанда оңай болды, дегенмен қазіргі кезде Джна балама болып табылады.[өзіндік зерттеу? ]

Сондай-ақ қараңыз

Әдебиеттер тізімі

  1. ^ «Java интерфейсіне шолу». Java Native Interface бағдарламашысының нұсқаулығы және сипаттамасы. Алынған 2018-12-27.
  2. ^ «Java-дан ассамблея тіл бағдарламаларын шақыру». Java.net. 2006-10-19. Архивтелген түпнұсқа 2008-03-30. Алынған 2007-10-06.
  3. ^ «Ассамблея тіл бағдарламаларынан Java қосымшаларын іске қосу». Java.net. 2006-10-19. Архивтелген түпнұсқа 2007-10-11. Алынған 2007-10-04.
  4. ^ Шақыру API. Sun Microsystems. https://docs.oracle.com/kz/java/javase/11/docs/specs/jni/invocation.html
  5. ^ «JNI типтері және мәліметтер құрылымы».
  6. ^ «java - JNI қоңырауларын баяу етеді? - Stack Overflow».

Библиография

Сыртқы сілтемелер