"यदि कोई कर्मचारी अपना काम अच्छी तरह से करना चाहता है, तो उसे पहले अपने औजारों को तेज करना होगा।" - कन्फ्यूशियस, "द एनालेक्ट्स ऑफ कन्फ्यूशियस। लू लिंगगोंग"
मुखपृष्ठ > प्रोग्रामिंग > MacOS API को कॉल करने के लिए जावा नेटिव एक्सेस (JNA) का उपयोग करना

MacOS API को कॉल करने के लिए जावा नेटिव एक्सेस (JNA) का उपयोग करना

2024-11-09 को प्रकाशित
ब्राउज़ करें:889

Using Java Native Access (JNA) to call MacOS API

परिचय

MacOS API के साथ JNA का उपयोग कैसे करें इसके बारे में यहां एक सरल उदाहरण दिया गया है। मैं इसे समझाने नहीं जा रहा हूं, क्योंकि मैं अभी भी सीख रहा हूं, लेकिन मैं इसे समझने में आसान बनाने और अन्य उद्देश्यों के लिए इसे कैसे करना है इसके बारे में बुनियादी विचार प्राप्त करने के लिए कोड को न्यूनतम रखता हूं।

अधिकांश कोड इंटेलिज-कम्युनिटी (अपाचे लाइसेंस) से है।

निर्भरता

हमें बस jna-प्लेटफ़ॉर्म की आवश्यकता है।


  net.java.dev.jna
  jna-platform
  5.13.0

कोड

पूरी तरह से 4 स्रोत कोड फ़ाइलें हैं। आईडी को बिना किसी संशोधन के IntelliJ से कॉपी किया गया है। MyFoundation और MyFoundationLibrary को क्रमशः फाउंडेशन और फाउंडेशनलाइब्रेरी से अलग किया गया है।

एप्लीकेशन.जावा

package org.example;

import com.sun.jna.Pointer;

import static org.example.MyFoundation.*;

public class Application {

    public static void main(String[] args) throws Exception {
        ID processInfoCls = getObjcClass("NSProcessInfo");
        Pointer processInfoSel = createSelector("processInfo");
        Pointer processNameSel = createSelector("processName");

        ID processInfo = invoke(processInfoCls, processInfoSel);
        ID processNameNSString = invoke(processInfo, processNameSel);
        String processName = toStringViaUTF8(processNameNSString);
        System.out.println(processName);
    }

}

आईडी.जावा

package org.example;

import com.sun.jna.NativeLong;

public final class ID extends NativeLong {

    public ID() {
    }

    public ID(long peer) {
        super(peer);
    }

    public static final ID NIL = new ID(0L);

    public boolean booleanValue() {
        return intValue() != 0;
    }
}

MyFoundationLibrary.java

public interface MyFoundationLibrary extends Library {

    int kCFStringEncodingUTF8 = 0x08000100;

    ID objc_getClass(String className);

    Pointer sel_registerName(String selectorName);

    int CFStringGetLength(ID theString);

    byte CFStringGetCString(ID theString, byte[] buffer, int bufferSize, int encoding);

}

MyFoundation.java

package org.example;

import com.sun.jna.*;

import java.lang.reflect.Proxy;
import java.util.Collections;

public class MyFoundation {
    private static final MyFoundationLibrary myFoundationLibrary;
    private static final Function myObjcMsgSend;

    static {
        myFoundationLibrary = Native.load("Foundation", MyFoundationLibrary.class, Collections.singletonMap("jna.encoding", "UTF8"));
        NativeLibrary nativeLibrary = ((Library.Handler) Proxy.getInvocationHandler(myFoundationLibrary)).getNativeLibrary();
        myObjcMsgSend = nativeLibrary.getFunction("objc_msgSend");
    }

    public static ID getObjcClass(String className) {
        return myFoundationLibrary.objc_getClass(className);
    }

    public static Pointer createSelector(String s) {
        return myFoundationLibrary.sel_registerName(s);
    }

    private static Object [] prepInvoke(ID id, Pointer selector, Object[] args) {
        Object[] invokArgs = new Object[args.length   2];
        invokArgs[0] = id;
        invokArgs[1] = selector;
        System.arraycopy(args, 0, invokArgs, 2, args.length);
        return invokArgs;
    }

    public static ID invoke(final ID id, final Pointer selector, Object... args) {
        // objc_msgSend is called with the calling convention of the target method
        // on x86_64 this does not make a difference, but arm64 uses a different calling convention for varargs
        // it is therefore important to not call objc_msgSend as a vararg function
        return new ID(myObjcMsgSend.invokeLong(prepInvoke(id, selector, args)));
    }

    public static String toStringViaUTF8(ID cfString) {
        if (ID.NIL.equals(cfString)) return null;

        int lengthInChars = myFoundationLibrary.CFStringGetLength(cfString);
        int potentialLengthInBytes = 3 * lengthInChars   1; // UTF8 fully escaped 16 bit chars, plus nul

        byte[] buffer = new byte[potentialLengthInBytes];
        byte ok = myFoundationLibrary.CFStringGetCString(cfString, buffer, buffer.length, MyFoundationLibrary.kCFStringEncodingUTF8);
        if (ok == 0) throw new RuntimeException("Could not convert string");
        return Native.toString(buffer);
    }

}
विज्ञप्ति वक्तव्य इस लेख को फिर से पुनर्मुद्रित किया गया है: https://dev.to/franzwong/using-java-native-access-jna-to-call-call-macos-api-2pi0?1 यदि कोई उल्लंघन है, तो इसे हटाने के लिए [email protected] पर संपर्क करें।
नवीनतम ट्यूटोरियल अधिक>

चीनी भाषा का अध्ययन करें

अस्वीकरण: उपलब्ध कराए गए सभी संसाधन आंशिक रूप से इंटरनेट से हैं। यदि आपके कॉपीराइट या अन्य अधिकारों और हितों का कोई उल्लंघन होता है, तो कृपया विस्तृत कारण बताएं और कॉपीराइट या अधिकारों और हितों का प्रमाण प्रदान करें और फिर इसे ईमेल पर भेजें: [email protected] हम इसे आपके लिए यथाशीघ्र संभालेंगे।

Copyright© 2022 湘ICP备2022001581号-3