java जावा प्रोग्राम में डीएलएल में एक विधि को कैसे कॉल करें




dll jni (2)

मैं जेएनए का उपयोग कर डीएलएल में एक विधि को कॉल करने की कोशिश कर रहा हूं। अब तक डीएलएल का उपयोग कर लोड किया है

Runtime.getRuntime().load("myworkspace/test.dll");

यह डीएल एक विधि का उल्लंघन करता है जिसे मुझे एक्सेस करने की आवश्यकता है। मैं अपनी जावा फ़ाइल में डीएलएल में मौजूद विधि को कैसे कार्यान्वित कर सकता हूं। क्या मैं एक ऑब्जेक्ट या डीएलएल का कुछ बनाता हूं और फिर डॉट ऑपरेटर के बाद विधि का नाम प्राप्त करता हूं।


source :

package jnahelloworldtest;

import com.sun.jna.Library;
import com.sun.jna.Native;
import com.sun.jna.NativeLong;
import com.sun.jna.Platform;
import com.sun.jna.*;

/** Simple example of native library declaration and usage. */
public class Main {
    public interface simpleDLL extends Library {
        simpleDLL INSTANCE = (simpleDLL) Native.loadLibrary(
            (Platform.isWindows() ? "simpleDLL" : "simpleDLLLinuxPort"), simpleDLL.class);
        // it's possible to check the platform on which program runs, for example purposes we assume that there's a linux port of the library (it's not attached to the downloadable project)
        byte giveVoidPtrGetChar(Pointer param); // char giveVoidPtrGetChar(void* param);
        int giveVoidPtrGetInt(Pointer param);   //int giveVoidPtrGetInt(void* param);
        int giveIntGetInt(int a);               // int giveIntGetInt(int a);
        void simpleCall();                      // void simpleCall();
    }

    public static void main(String[] args) {

        simpleDLL sdll = simpleDLL.INSTANCE;

        sdll.simpleCall();  // call of void function

        int a = 3;
        int result1 = sdll.giveIntGetInt(a);  // calling function with int parameter&result
        System.out.println("giveIntGetInt("+a+"): " + result1);

        String testStr = "ToBeOrNotToBe";
        Memory mTest = new Memory(testStr.length()+1);  // '+1' remember about extra byte for \0 character!
        mTest.setString(0, testStr);
        String testReturn = mTest.getString(0); // you can see that String got properly stored in Memory object
        System.out.println("String in Memory:"+testReturn);

        Memory intMem = new Memory(4);  // allocating space
        intMem.setInt(0, 666); // setting allocated memory to an integer
        Pointer intPointer = intMem.getPointer(0);

        int int1 = sdll.giveVoidPtrGetInt(Pointer.NULL); // passing null, getting default result
        System.out.println("giveVoidPtrGetInt(null):" + int1); 
        int int2 = sdll.giveVoidPtrGetInt(intMem); // passing int stored in Memory object, getting it back
       //int int2 = sdll.giveVoidPtrGetInt(intPointer);  causes JVM crash, use memory object directly!
        System.out.println("giveVoidPtrGetInt(666):" + int2);

        byte char1 = sdll.giveVoidPtrGetChar(Pointer.NULL);  // passing null, getting default result
        byte char2 = sdll.giveVoidPtrGetChar(mTest);        // passing string stored in Memory object, getting first letter

        System.out.println("giveVoidPtrGetChar(null):" + (char)char1);
        System.out.println("giveVoidPtrGetChar('ToBeOrNotToBe'):" + (char)char2);

    }
}

डीएलएल लोड हो रहा है केवल सबसे आसान कदम है।

चूंकि जावा से डीएलएल की विधि को कॉल करना वास्तव में छोटा नहीं है, यह उत्तर केवल संकेतों का सारांश है जो आपको एक डीएलएल से फ़ंक्शन कॉल करने के लिए करना है। पूरी कहानी एक किताब भर जाएगी। और वास्तव में जेएनआई (जावा मूल इंटरफेस) के बारे में कई किताबें हैं।

किसी मूल पुस्तकालय में फ़ंक्शन को कॉल करने के लिए आपको अपने जावा क्लास में जावा कीवर्ड native साथ देशी के रूप में एक विधि घोषित करना होगा। इस विधि की घोषणा में शरीर नहीं होना चाहिए।

आपके डीएलएल से निर्यात किए गए फ़ंक्शन का नाम निम्न पैटर्न से मेल खाना चाहिए: Java_classname_methodname जहां classname कक्षा का नाम है जहां आपने मूल विधि विधि नाम घोषित किया है।

उदाहरण के लिए यदि आप मूल श्रेणी घोषित करते हैं तो private native void sayHello() आपकी कक्षा में MyClass DLL के फ़ंक्शन का नाम होगा: Java_MyClass_sayHello

यह भी ध्यान रखें कि फ़ंक्शन को सही कॉलिंग सम्मेलनों जेएनआईएक्सपोर्ट और जेएनआईसीओएल के साथ डीएलएल से निर्यात किया जाना चाहिए जो हेडर फ़ाइल jni.h में परिभाषित किया गया है जो आपके जेडीके के साथ आता है (फ़ोल्डर शामिल करें)

जावा से बुलाए जाने वाले डीएलएल के प्रत्येक कार्य में पहले पैरामीटर (JNIEnv *env, jobject obj) रूप में दो "छुपा" तर्क होना चाहिए। env कॉलिंग JVM के लिए एक सूचक है जो आपको JVM में कॉलबैक की अनुमति देता है और obj वह ऑब्जेक्ट है जिस से विधि को कॉल किया गया था।

तो हमारे उदाहरण में डीएलएल की विधि की पूरी परिभाषा होगी: JNIEXPORT void JNICALL Java_MyClass_sayHello(JNIEnv *, jobject);

जेएनआई के इन प्रतिबंधों के कारण आपके कोड से बुलाया गया एक डीएलएल आपके कोड के लिए निश्चित रूप से बनाया जाना चाहिए। जावा से मनमाने ढंग से डीएलएल का उपयोग करने के लिए आपको आम तौर पर जेएनआई के सम्मेलनों के साथ एक अनुकूल डीएलएल बनाना होता है जो स्वयं "लक्ष्य" डीएलएल लोड करता है और आवश्यक कार्यों को कॉल करता है।

अपने एडाप्टर डीएलएल के लिए सही हेडर उत्पन्न करने के लिए आप जेडीके के साथ भेजे गए टूल जावा का उपयोग कर सकते हैं। यह टूल हेडर को आपके जावा कोड से लागू करने के लिए जेनरेट करेगा।

अधिक जानकारी के लिए जेएनआई के दस्तावेज देशी कोड से जेवीएम के साथ बातचीत के बारे में सभी सवालों को शामिल करेंगे। http://docs.oracle.com/javase/7/docs/technotes/guides/jni/





jna