Hier ist ein einfaches Beispiel für die Verwendung von JNA mit der MacOS-API. Ich werde das nicht erklären, da ich noch am Lernen bin, aber ich halte den Code auf ein Minimum, um ihn leichter zu verstehen und eine grundlegende Vorstellung davon zu bekommen, wie man ihn für andere Zwecke umsetzen kann.
Der größte Teil des Codes stammt von der Intellij-Community (Apache-Lizenz).
Alles was wir brauchen ist eine JNA-Plattform.
<dependency> <groupId>net.java.dev.jna</groupId> <artifactId>jna-platform</artifactId> <version>5.13.0</version> </dependency>
Es gibt insgesamt 4 Quellcodedateien. Die ID wird ohne Änderung von IntelliJ kopiert. MyFoundation und MyFoundationLibrary werden aus Foundation bzw. FoundationLibrary gekürzt.
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); } }
Das obige ist der detaillierte Inhalt vonVerwenden von Java Native Access (JNA) zum Aufrufen der MacOS-API. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!