إليك مثال بسيط حول كيفية استخدام JNA مع MacOS API. لن أشرح هذا، لأنني مازلت أتعلم، لكنني أحتفظ بالحد الأدنى من التعليمات البرمجية لتسهيل الفهم والحصول على الفكرة الأساسية حول كيفية القيام بذلك لأغراض أخرى.
معظم الكود مأخوذ من Intellij-Community (ترخيص Apache).
كل ما نحتاجه هو منصة jna.
net.java.dev.jna jna-platform 5.13.0
يوجد إجمالي 4 ملفات كود المصدر. يتم نسخ المعرف من IntelliJ دون تعديل. تم اقتطاع MyFoundation وMyFoundationLibrary من Foundation وFoundationLibrary على التوالي.
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; } }
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); }
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); } }
تنصل: جميع الموارد المقدمة هي جزئيًا من الإنترنت. إذا كان هناك أي انتهاك لحقوق الطبع والنشر الخاصة بك أو الحقوق والمصالح الأخرى، فيرجى توضيح الأسباب التفصيلية وتقديم دليل على حقوق الطبع والنشر أو الحقوق والمصالح ثم إرسالها إلى البريد الإلكتروني: [email protected]. سوف نتعامل مع الأمر لك في أقرب وقت ممكن.
Copyright© 2022 湘ICP备2022001581号-3