এই ধাঁধাটি খেলার সময় (এটি একটি জাভা কীওয়ার্ড ট্রিভিয়া গেম), আমি native
কীওয়ার্ডটি পেলাম ।
জাভার নেটিভ কীওয়ার্ডটি কী জন্য ব্যবহৃত হয়?
এই ধাঁধাটি খেলার সময় (এটি একটি জাভা কীওয়ার্ড ট্রিভিয়া গেম), আমি native
কীওয়ার্ডটি পেলাম ।
জাভার নেটিভ কীওয়ার্ডটি কী জন্য ব্যবহৃত হয়?
উত্তর:
মূল native
শব্দটি JNI (জাভা নেটিভ ইন্টারফেস) ব্যবহার করে স্থানীয় কোডে প্রয়োগ করা হয়েছে তা বোঝাতে কীওয়ার্ডটি কোনও পদ্ধতিতে প্রয়োগ করা হয়।
ন্যূনতম চলমান উদাহরণ
Main.java
public class Main {
public native int square(int i);
public static void main(String[] args) {
System.loadLibrary("Main");
System.out.println(new Main().square(2));
}
}
Main.c
#include <jni.h>
#include "Main.h"
JNIEXPORT jint JNICALL Java_Main_square(
JNIEnv *env, jobject obj, jint i) {
return i * i;
}
সংকলন এবং চালান:
sudo apt-get install build-essential openjdk-7-jdk
export JAVA_HOME='/usr/lib/jvm/java-7-openjdk-amd64'
javac Main.java
javah -jni Main
gcc -shared -fpic -o libMain.so -I${JAVA_HOME}/include \
-I${JAVA_HOME}/include/linux Main.c
java -Djava.library.path=. Main
আউটপুট:
4
উবুন্টু 14.04 এএমডি 64 তে পরীক্ষিত। এছাড়াও ওরাকল জেডিকে 1.8.0_45 এর সাথে কাজ করেছে।
আপনার সাথে খেলতে গিটহাবের উদাহরণ ।
জাভা প্যাকেজ / ফাইলের নামগুলিতে বোঝা উচিত _1
সি ফাংশন নাম দিয়ে উল্লিখিত হিসাবে: এন্ড্রয়েড প্যাকেজের নাম অ্যান্ড্রয়েড প্যাকেজ নাম জেএনআই ফাংশন শুরু
ব্যাখ্যা
native
আপনি করতে পারবেন:
এটি ব্যবহৃত হতে পারে:
নিম্ন বহনযোগ্যতার ট্রেড অফ দিয়ে।
আপনার পক্ষে সি থেকে জাভা কল করাও সম্ভব, তবে আপনাকে অবশ্যই প্রথমে সি তে একটি জেভিএম তৈরি করতে হবে: সি ++ থেকে জাভা ফাংশনগুলি কীভাবে কল করবেন?
অ্যান্ড্রয়েড এনডিকে
ধারণাটি এই প্রসঙ্গে ঠিক একই, আপনাকে সেট আপ করতে অ্যান্ড্রয়েড বয়লারপ্লেট ব্যবহার করতে হবে except
অফিসিয়াল এনডিকে রিপোজিটরিতে "ক্যানোনিকাল" উদাহরণ রয়েছে যেমন হ্যালো-জনি অ্যাপ্লিকেশন:
আপনি unzip
একটি .apk
NDK অ্যান্ড্রয়েড হে উপর সঙ্গে, আপনি প্রাক কম্পাইল দেখতে পারেন .so
অধীনে নেটিভ কোড সাথে সঙ্গতিপূর্ণ যে lib/arm64-v8a/libnative-lib.so
।
টোডো নিশ্চিত করুন: তদুপরি,, file /data/app/com.android.appname-*/oat/arm64/base.odex
বলেছে এটি একটি ভাগ করা লাইব্রেরি, যা আমার মনে হয় এওটি প্রিম্পম্পাইলড। ডেক্সটি এআরটিতে জাভা ফাইলগুলির সাথে সম্পর্কিত, আরও দেখুন: অ্যান্ড্রয়েডে ওডেক্স ফাইলগুলি কী কী? তাই সম্ভবত জাভা আসলে একটি native
ইন্টারফেস মাধ্যমে চালানো হয় ?
ওপেনজেডকে 8-তে উদাহরণ
আসুন সন্ধান করি কোথায় Object#clone
jdk8u60-b27 এ সংজ্ঞায়িত করা হয়েছে।
আমরা উপসংহারে পৌঁছে যাব যে এটি একটি native
কল দিয়ে কার্যকর করা হয়েছে ।
প্রথমে আমরা খুঁজে পাই:
find . -name Object.java
যা আমাদেরকে জেডিকে / এসসিআর / শেয়ার / ক্লাস / জাভা / ল্যাং / অবজেক্ট.জভাতে পৌঁছে দেয় # l212 :
protected native Object clone() throws CloneNotSupportedException;
এখন শক্ত অংশটি এসেছে, যেখানে সন্ধান সমস্ত ক্লান্তির মাঝে ক্লোন রয়েছে। যে প্রশ্নটি আমাকে সহায়তা করেছিল তা হ'ল:
find . -iname object.c
যা সি বা সি ++ ফাইলগুলির সন্ধান করবে যা অবজেক্টের স্থানীয় পদ্ধতি প্রয়োগ করতে পারে। এটি আমাদেরকে জেডিকে / শেয়ার / নেটিভ / জাভা / ল্যাং / অবজেক্ট.সি এর দিকে নিয়ে যায় # l47 :
static JNINativeMethod methods[] = {
...
{"clone", "()Ljava/lang/Object;", (void *)&JVM_Clone},
};
JNIEXPORT void JNICALL
Java_java_lang_Object_registerNatives(JNIEnv *env, jclass cls)
{
(*env)->RegisterNatives(env, cls,
methods, sizeof(methods)/sizeof(methods[0]));
}
যা আমাদের JVM_Clone
প্রতীক নিয়ে যায়:
grep -R JVM_Clone
যা আমাদের হটস্পট / এসসিআর / শেয়ার / ভিএম / প্রাইমস / জেভিএম.cpp # l580 এ নিয়ে যায় :
JVM_ENTRY(jobject, JVM_Clone(JNIEnv* env, jobject handle))
JVMWrapper("JVM_Clone");
একগুচ্ছ ম্যাক্রো প্রসারিত করার পরে, আমরা এই সিদ্ধান্তে পৌঁছেছি যে এটি সংজ্ঞা পয়েন্ট।
static
native
জাভা পদ্ধতির জন্য, সি ++ ফাংশনের দ্বিতীয় প্যারামিটারটি টাইপের jclass
এবং না jobject
।
এটি একটি পদ্ধতি চিহ্নিত করে, এটি জাভাতে নয়, অন্য ভাষায় প্রয়োগ করা হবে। এটি জেএনআই (জাভা নেটিভ ইন্টারফেস) এর সাথে একসাথে কাজ করে।
পারফরম্যান্স সমালোচনামূলক বিভাগগুলি লেখার জন্য অতীতে নেটিভ পদ্ধতি ব্যবহার করা হত তবে জাভা দ্রুত গতিতে আসার সাথে এখন এটি খুব কম দেখা যায়। স্থানীয় পদ্ধতি বর্তমানে প্রয়োজন হয় যখন
আপনার জাভা থেকে একটি লাইব্রেরি কল করতে হবে যা অন্য ভাষায় লেখা।
আপনার সিস্টেম বা হার্ডওয়্যার রিসোর্সগুলি অ্যাক্সেস করতে হবে যা কেবলমাত্র অন্য ভাষা থেকে পৌঁছতে পারে (সাধারণত সি)। প্রকৃতপক্ষে, অনেকগুলি সিস্টেম ফাংশন যা প্রকৃত কম্পিউটারের সাথে যোগাযোগ করে (উদাহরণস্বরূপ ডিস্ক এবং নেটওয়ার্ক আইও) কেবল এটি করতে পারে কারণ তারা নেটিভ কোডকে কল করে।
এছাড়াও দেখুন জাভা নেটিভ ইন্টারফেস স্পেসিফিকেশন
currentTimeMillis
অংশ এবং এগুলি এন্টারনেট করা হয়েছে native
কারণ বাস্তবায়নটি জেডিকে উত্স কোডেই রয়েছে । এটি প্রয়োগের পক্ষে সমাবেশ ভাষা ব্যবহার করা খুব সম্ভব নয়; এটি সম্ভবত অপারেটিং সিস্টেমের একটি API পদ্ধতি কল করে যা JVM উপরে চলছে। উদাহরণস্বরূপ উইন্ডোজ এ এটি GetSystemTime
কার্নেল 32.dll এ একটি ডিএলএল পদ্ধতি কল করতে পারে। অন্য একটি ওএসে এটির আলাদা বাস্তবায়ন হবে। তবে আপনি যখন native
লিখছেন এমন কোনও পদ্ধতির জন্য ব্যবহার করেন (জেডিকে পদ্ধতির বিপরীতে) আপনাকে জেএনআই ব্যবহার করে বাস্তবায়ন সরবরাহ করতে হবে।
currentTimeMillis
দেশীয় হিসাবে চিহ্নিত করা হয়েছে java.lang.System
যাতে এটি জেএনআই ব্যবহার করে, তাই না?
থেকে সরাসরি জাভা ল্যাঙ্গুয়েজ স্পেসিফিকেশন :
এমন একটি পদ্ধতি যা
native
প্ল্যাটফর্ম-নির্ভর কোডে প্রয়োগ করা হয়, সাধারণত অন্য প্রোগ্রামিং ভাষায় যেমন C, C ++, FORTRAN বা সমাবেশ ভাষাতে লেখা হয়। কোনওnative
পদ্ধতির শৃঙ্খলাটি কেবল একটি সেমিকোলন হিসাবে দেওয়া হয় যা ইঙ্গিত করে যে বাস্তবায়নটি একটি ব্লকের পরিবর্তে বাদ পড়েছে।
যেমন স্ল্যাक्स উত্তর দিয়েছে, native
শব্দটি স্থানীয় কোড কল করার জন্য।
এটি জাভাস্ক্রিপ্ট পদ্ধতি প্রয়োগের জন্য জিডব্লিউটি ব্যবহার করে ।
নেটিভ কোড প্রয়োগ করে এমন ফাংশনগুলি দেশীয় ঘোষিত হয়।
জাভা নেটিভ ইন্টারফেস (জেএনআই) একটি প্রোগ্রামিং ফ্রেমওয়ার্ক যা জাভা ভার্চুয়াল মেশিনে (জেভিএম) চলমান জাভা কোডটি কল করতে এবং স্থানীয় অ্যাপ্লিকেশনগুলি (একটি হার্ডওয়্যার এবং অপারেটিং সিস্টেমের প্ল্যাটফর্মের জন্য নির্দিষ্ট প্রোগ্রাম) এবং লিখিত গ্রন্থাগারগুলিতে কল করতে সক্ষম করে programming অন্যান্য ভাষা যেমন সি, সি ++ এবং সমাবেশ।
নেটিভ জাভাতে একটি কীওয়ার্ড, যা ব্যবহারহীন কাঠামো (পদ্ধতি) বিমূর্তের মতো তৈরি করতে ব্যবহৃত হয় তবে এটি প্ল্যাটফর্ম নির্ভর যেমন স্থানীয় কোড এবং জাভা স্ট্যাক নয় বরং নেটিভ স্ট্যাক থেকে চালানো হয়।
জাভা native
পদ্ধতিটি কার্যকরী বা পারফরম্যান্সের কারণে জাভা কোডের জন্য ওএস স্থানীয় কোড কল করার জন্য একটি প্রক্রিয়া সরবরাহ করে।
উদাহরণ:
606 public native int availableProcessors();
617 public native long freeMemory();
630 public native long totalMemory();
641 public native long maxMemory();
664 public native void gc();
Runtime.class
ওপেনজেডিকেতে সম্পর্কিত ফাইলটিতে অবস্থিত JAVA_HOME/jmods/java.base.jmod/classes/java/lang/Runtime.class
, এই পদ্ধতিগুলি রয়েছে এবং তাদের ACC_NATIVE
( 0x0100
) দিয়ে ট্যাগ করেছে এবং এই পদ্ধতিগুলিতে কোড বৈশিষ্ট্য থাকে না , যার অর্থ এই পদ্ধতিটিতে Runtime.class
ফাইলটিতে কোনও আসল কোডিং যুক্তি থাকে না :
availableProcessors
: স্থানীয় হিসাবে ট্যাগ এবং কোনও কোড অ্যাট্রিবিউটfreeMemory
: স্থানীয় হিসাবে ট্যাগ এবং কোনও কোড অ্যাট্রিবিউটtotalMemory
: স্থানীয় হিসাবে ট্যাগ এবং কোনও কোড অ্যাট্রিবিউটmaxMemory
: স্থানীয় হিসাবে ট্যাগ এবং কোনও কোড অ্যাট্রিবিউটgc
: স্থানীয় হিসাবে ট্যাগ এবং কোনও কোড অ্যাট্রিবিউটপ্রকৃতপক্ষে কোডিং যুক্তিটি সংশ্লিষ্ট রানটাইম। সি ফাইলটিতে রয়েছে:
42 #include "java_lang_Runtime.h"
43
44 JNIEXPORT jlong JNICALL
45 Java_java_lang_Runtime_freeMemory(JNIEnv *env, jobject this)
46 {
47 return JVM_FreeMemory();
48 }
49
50 JNIEXPORT jlong JNICALL
51 Java_java_lang_Runtime_totalMemory(JNIEnv *env, jobject this)
52 {
53 return JVM_TotalMemory();
54 }
55
56 JNIEXPORT jlong JNICALL
57 Java_java_lang_Runtime_maxMemory(JNIEnv *env, jobject this)
58 {
59 return JVM_MaxMemory();
60 }
61
62 JNIEXPORT void JNICALL
63 Java_java_lang_Runtime_gc(JNIEnv *env, jobject this)
64 {
65 JVM_GC();
66 }
67
68 JNIEXPORT jint JNICALL
69 Java_java_lang_Runtime_availableProcessors(JNIEnv *env, jobject this)
70 {
71 return JVM_ActiveProcessorCount();
72 }
এবং এই C
কোডিংটি libjava.so
(লিনাক্স) বা libjava.dll
(উইন্ডোজ) ফাইলে সংকলিত রয়েছে , এখানে অবস্থিত JAVA_HOME/jmods/java.base.jmod/lib/libjava.so
:
উল্লেখ