」工欲善其事,必先利其器。「—孔子《論語.錄靈公》
首頁 > 程式設計 > 使用Java Native Access (JNA)呼叫MacOS API

使用Java Native Access (JNA)呼叫MacOS API

發佈於2024-11-09
瀏覽:954

Using Java Native Access (JNA) to call MacOS API

介紹

這是一個關於如何將 JNA 與 MacOS API 結合使用的簡單範例。我不會解釋這一點,因為我仍在學習,但我將程式碼保持最少,以便更容易理解並了解如何將其用於其他目的的基本概念。

大部分程式碼來自 Intellij-Community(Apache 授權)。

依賴性

我們需要的是 jna-platform。


  net.java.dev.jna
  jna-platform
  5.13.0

程式碼

原始碼檔案共有4個。 ID 是從 IntelliJ 複製而來,未經修改。 MyFoundation 和 MyFoundationLibrary 分別從 Foundation 和 FoundationLibrary 中刪除。

應用程式.java

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);
    }

}

ID.java

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-macos-api-2pi0?1如有侵犯,請聯絡[email protected]刪除
最新教學 更多>
  • 使用socket.io的聊天應用程序
    使用socket.io的聊天應用程序
    本文演示了使用socket.io和backbone.js構建一個簡單的聊天應用程序。 socket.io促進實時,交互式Web應用程序,而Backbone.js則構造了客戶端代碼,以進行更好的管理和解耦。 假定對Node.js和Express的熟悉;骨乾和下劃線知識是有益的。 [2 聊天應用程序...
    程式設計 發佈於2025-03-22
  • 方法鏈如何使jQuery代碼更加簡潔有效?
    方法鏈如何使jQuery代碼更加簡潔有效?
    如何簡化jQuery代碼與其他Javascript框架相比,JQuery的重要優勢之一是其對像或方法鏈接。要了解鍊式的工作原理,讓我們深入研究一個簡化的示例。 考慮一個具有多個方法的對象: 在此示例中,每個方法返回調用對象本身。結果,您可以將無縫的鏈方法無縫地鏈方法:由於返回的對象而成為可能。執行...
    程式設計 發佈於2025-03-22
  • 如何使用組在MySQL中旋轉數據?
    如何使用組在MySQL中旋轉數據?
    在關係數據庫中使用mySQL組使用mySQL組進行查詢結果,在關係數據庫中使用MySQL組,轉移數據的數據是指重新排列的行和列的重排以增強數據可視化。在這裡,我們面對一個共同的挑戰:使用組的組將數據從基於行的基於列的轉換為基於列。 Let's consider the following ...
    程式設計 發佈於2025-03-22
  • 如何在鏈接方法上調用GO的Vector3 struct時如何避免錯誤?
    如何在鏈接方法上調用GO的Vector3 struct時如何避免錯誤?
    在嘗試在Vector3 Struct上鍊接方法調用時,在Vector3方法調用中管理Pointers ,您可能會遇到與值地址和調用指針方法有關的錯誤。本文研究了這些錯誤,並指導您如何解決這些錯誤。 理解指針和值接收器 workarounds 解決此問題,您有幾個選項:更改vector3方法具有值...
    程式設計 發佈於2025-03-22
  • 您可以強行cancel一個JavaScript承諾嗎?
    您可以強行cancel一個JavaScript承諾嗎?
    在JavaScript編程領域中是否有可能強制取消承諾? ,承諾是管理異步操作的強大機制。但是,問題經常出現:是否有可能迫使 - cancel一個承諾? ES6承諾:一個status quo 的狀態,不幸的是,在ES6的當前狀態下,諾言並不是內在支持取消​​。這是因為取消諾言涉及復雜的設計注意...
    程式設計 發佈於2025-03-22
  • \“(1)vs.(;;):編譯器優化是否消除了性能差異?\”
    \“(1)vs.(;;):編譯器優化是否消除了性能差異?\”
    答案: 在大多數現代編譯器中,while(1)和(1)和(;;)之間沒有性能差異。編譯器: perl: 1 輸入 - > 2 2 NextState(Main 2 -E:1)V-> 3 9 Leaveloop VK/2-> A 3 toterloop(next-> 8 last-> 9 ...
    程式設計 發佈於2025-03-22
  • 如何使用字段函數在()子句順序中訂購mySQL結果?
    如何使用字段函數在()子句順序中訂購mySQL結果?
    使用字段函數在MySQL中使用()順序 字段函數採用兩個參數:一個字段名稱和值列表。它返回與字段值匹配的列表中第一個值的索引。例如,以下查詢將返回值1、2、3的列的列“ ID”的列,其中值為3、2或1:選擇ID,field(id,3、2、1)作為從table_name; 選擇ID,field(ID...
    程式設計 發佈於2025-03-22
  • 如何在移動設備上堆疊Bootstrap 4 Divs並將它們並排放在桌面上?
    如何在移動設備上堆疊Bootstrap 4 Divs並將它們並排放在桌面上?
    用bootstrap 4:堆疊在移動設備上,在桌面上並排置於桌面 desktop.Solution:Disable Flexbox for Larger Widths:Bootstrap 4's flexbox assigns equal heights to columns.為了防止這種...
    程式設計 發佈於2025-03-22
  • 在程序退出之前,我需要在C ++中明確刪除堆的堆分配嗎?
    在程序退出之前,我需要在C ++中明確刪除堆的堆分配嗎?
    在C中的顯式刪除 在C中的動態內存分配時,開發人員通常會想知道是否有必要在heap-procal extrable exit exit上進行手動調用“ delete”操作員,但開發人員通常會想知道是否需要手動調用“ delete”操作員。本文深入研究了這個主題。 在C主函數中,使用了動態分配變量(...
    程式設計 發佈於2025-03-22
  • python 3.5中的Asyncio:何時使用,何時避免?
    python 3.5中的Asyncio:何時使用,何時避免?
    在python 3.5中的asyncio:何時使用,何時避免等待在使用Python 3.5中使用Asyncio時,對於使用適當的方案使用了適當的方案,請使用適當的方案使用the await toyt toynt toynt toynt toym && && && && && &&&固。等待等待進行...
    程式設計 發佈於2025-03-22
  • 這是您可以用CSS替換JavaScript的一些內容
    這是您可以用CSS替換JavaScript的一些內容
    以下20件事可以使用CSS替換JavaScript,使用其高級能力,例如動畫,選擇器,偽元素和過渡: 工具tip councation 下拉菜單如果您對更多選項感興趣,請單擊以下鏈接:https://chat-to..dev/post?id=700
    程式設計 發佈於2025-03-22
  • 如何檢查對像是否具有Python中的特定屬性?
    如何檢查對像是否具有Python中的特定屬性?
    方法來確定對象屬性存在尋求一種方法來驗證對像中特定屬性的存在。考慮以下示例,其中嘗試訪問不確定屬性會引起錯誤: >>> a = someClass() >>> A.property Trackback(最近的最新電話): 文件“ ”,第1行, attributeError:SomeClass實...
    程式設計 發佈於2025-03-22
  • 如何在簡單的返回類型扣除範圍之外使用C ++ 14的`electType(auto)`?
    如何在簡單的返回類型扣除範圍之外使用C ++ 14的`electType(auto)`?
    dectype(auto)的Versatile應用程序超出返回類型扣除在通用代碼中返回類型轉發對於非傳統函數,可以明確指定所需的返回類型(參考或值)。但是,在通用代碼中,轉發返回類型的機制至關重要。 DeclType(Auto)通過提供一種能夠完美地轉發返回類型的方法,無論其類型如何。 在遞歸模...
    程式設計 發佈於2025-03-22
  • JavaScript可以訪問無效的CSS屬性嗎?
    JavaScript可以訪問無效的CSS屬性嗎?
    可以檢索無效的css屬性值? custom cass properties,用名稱以dash為dash,提供用於定義和訪問應用程序中的唯一樣式的機構。但是,如果JavaScript訪問這些自定義屬性的值,如果瀏覽器無效或未識別它們? 當遇到無效的屬性名稱(例如“ -my-foo”)時,此對象通...
    程式設計 發佈於2025-03-22

免責聲明: 提供的所有資源部分來自互聯網,如果有侵犯您的版權或其他權益,請說明詳細緣由並提供版權或權益證明然後發到郵箱:[email protected] 我們會在第一時間內為您處理。

Copyright© 2022 湘ICP备2022001581号-3