下面列出了怎么用com.sun.jna.Native的API类实例代码及写法,或者点击链接到github查看源代码。
public static void main(String[] args) {
final User32 user32 = User32.INSTANCE;
user32.EnumWindows(new WinUser.WNDENUMPROC() {
int count = 0;
@Override
public boolean callback(WinDef.HWND hwnd, Pointer pointer) {
byte[] windowText = new byte[512];
byte[] className = new byte[512];
user32.GetWindowTextA(hwnd, windowText, 512);
user32.GetClassNameA(hwnd, className, 512);
String title = Native.toString(windowText);
String classN = Native.toString(className);
// get rid of this if block if you want all windows regardless of whether
// or not they have text
if (title.isEmpty()) {
return true;
}
System.out.println("Title: " + title + " Class name: " + classN);
return true;
}
},null);
}
/**
* Forcibly set focus to the given component
*
*/
public static void requestForeground(Frame frame)
{
// SetForegroundWindow can't set iconified windows to foreground, so set the
// frame state to normal first
frame.setState(Frame.NORMAL);
User32 user32 = User32.INSTANCE;
// Windows does not allow any process to set the foreground window, but it will if
// the process received the last input event. So we send a F22 key event to the process.
// https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-setforegroundwindow
WinUser.INPUT input = new WinUser.INPUT();
input.type = new WinDef.DWORD(WinUser.INPUT.INPUT_KEYBOARD);
input.input.ki.wVk = new WinDef.WORD(0x85); // VK_F22
user32.SendInput(new WinDef.DWORD(1), (WinUser.INPUT[]) input.toArray(1), input.size());
// Now we may set the foreground window
WinDef.HWND hwnd = new WinDef.HWND(Native.getComponentPointer(frame));
user32.SetForegroundWindow(hwnd);
}
public byte[] next() {
levelDB.checkDatabaseOpen();
checkIteratorOpen();
PointerByReference resultLengthPointer = new PointerByReference();
PointerByReference resultPointer = LevelDBNative.leveldb_iter_key(iterator, resultLengthPointer);
long resultLength;
if (Native.POINTER_SIZE == 8) {
resultLength = resultLengthPointer.getPointer().getLong(0);
} else {
resultLength = resultLengthPointer.getPointer().getInt(0);
}
byte[] key = resultPointer.getPointer().getByteArray(0, (int) resultLength);
LevelDBNative.leveldb_iter_next(iterator);
return key;
}
@Override
public void lockCurrentMemory() {
if (mlockall(MCL_CURRENT) == 0) {
return;
}
final int errno = Native.getLastError();
final String msg, reason;
if (errno == EPERM) {
reason = "insufficient privileges";
}
else if (errno == ENOMEM) {
reason = "insufficient free space";
}
else {
reason = "errno=" + errno;
}
msg = "Unable to lock memory due to " + reason
+ ". Please check the RLIMIT_MEMLOCK soft resource limit "
+ "(ulimit -l) and increase the available memory if needed.";
throw new IllegalStateException(msg);
}
protected File getDestinationOfDownloadFile(final EdsDirectoryItemInfo dirItemInfo, @Nullable final File folderDestination, @Nullable final String filename) {
final String itemFilename = Native.toString(dirItemInfo.szFileName, DEFAULT_CHARSET.name());
final String itemFileExtension = Files.getFileExtension(itemFilename);
final File saveFolder = folderDestination == null ? SYSTEM_TEMP_DIR : folderDestination;
final String saveFilename;
if (StringUtils.isBlank(filename)) {
saveFilename = itemFilename;
} else {
final String fileExtension = Files.getFileExtension(filename);
if (StringUtils.isBlank(fileExtension)) {
saveFilename = filename + "." + itemFileExtension;
} else {
if (fileExtension.equalsIgnoreCase(itemFileExtension)) {
saveFilename = filename;
} else {
saveFilename = filename + "." + itemFileExtension;
}
}
}
saveFolder.mkdirs();
return new File(saveFolder, saveFilename);
}
public EventLogRecord(Pointer pevlr) {
_record = new EVENTLOGRECORD(pevlr);
_source = pevlr.getString(_record.size(), true);
// data
if (_record.DataLength.intValue() > 0) {
_data = pevlr.getByteArray(_record.DataOffset.intValue(),
_record.DataLength.intValue());
}
// strings
if (_record.NumStrings.intValue() > 0) {
ArrayList<String> strings = new ArrayList<>();
int count = _record.NumStrings.intValue();
long offset = _record.StringOffset.intValue();
while (count > 0) {
String s = pevlr.getString(offset, true);
strings.add(s);
offset += s.length() * Native.WCHAR_SIZE;
offset += Native.WCHAR_SIZE;
count--;
}
_strings = strings.toArray(new String[strings.size()]);
}
}
protected ProcessEnvironment createProcessEnvironment(OperatingSystem operatingSystem) {
if (useNativePlatform) {
try {
io.rubygrapefruit.platform.Process process = io.rubygrapefruit.platform.Native.get(Process.class);
return new NativePlatformBackedProcessEnvironment(process);
} catch (NativeIntegrationUnavailableException ex) {
LOGGER.debug("Native-platform process integration is not available. Continuing with fallback.");
}
}
try {
if (operatingSystem.isUnix()) {
return new LibCBackedProcessEnvironment(get(LibC.class));
} else {
return new UnsupportedEnvironment();
}
} catch (LinkageError e) {
// Thrown when jna cannot initialize the native stuff
LOGGER.debug("Unable to load native library. Continuing with fallback. Failure: {}", format(e));
return new UnsupportedEnvironment();
}
}
/**
* Init the native binding to the underlying system library.
*/
public static void init() throws UnsatisfiedLinkError {
Native.unregister(JOpenVRLibrary.class);
String path = System.getProperty(JNA_OPENVR_LIBRARY_PATH);
if (path != null){
JNA_LIBRARY_NAME = path;
logger.config("Using OpenVR implementation located at "+JNA_LIBRARY_NAME);
JNA_NATIVE_LIB = NativeLibrary.getInstance(JOpenVRLibrary.JNA_LIBRARY_NAME);
Native.register(JOpenVRLibrary.class, JOpenVRLibrary.JNA_NATIVE_LIB);
} else {
JNA_LIBRARY_NAME = "openvr_api";
logger.config("Using embedded OpenVR implementation "+JOpenVRLibrary.JNA_LIBRARY_NAME);
JNA_NATIVE_LIB = NativeLibrary.getInstance(JOpenVRLibrary.JNA_LIBRARY_NAME);
Native.register(JOpenVRLibrary.class, JOpenVRLibrary.JNA_NATIVE_LIB);
}
}
private void setHasFrame(JFrame frame, boolean hasFrame) {
if (!this.frameless) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
System.out.println(windowName + " hasFrame=" + hasFrame);
WinDef.HWND hWnd = new WinDef.HWND();
hWnd.setPointer(Native.getComponentPointer(frame));
LayoutFrame.this.externalWindowObserver.setHasFrame(hWnd, hasFrame);
frame.setResizable(hasFrame);
frame.invalidate();
frame.validate();
frame.repaint();
SwingUtilities.updateComponentTreeUI(frame);
}
});
}
}
private static void restartOnWindows(@Nonnull final String... beforeRestart) throws IOException {
Kernel32 kernel32 = Native.loadLibrary("kernel32", Kernel32.class);
Shell32 shell32 = Native.loadLibrary("shell32", Shell32.class);
final int pid = kernel32.GetCurrentProcessId();
final IntByReference argc = new IntByReference();
Pointer argv_ptr = shell32.CommandLineToArgvW(kernel32.GetCommandLineW(), argc);
final String[] argv = argv_ptr.getWideStringArray(0, argc.getValue());
kernel32.LocalFree(argv_ptr);
doScheduleRestart(new File(ContainerPathManager.get().getBinPath(), "restarter.exe"), ContainerPathManager.get().getAppHomeDirectory(), commands -> {
Collections.addAll(commands, String.valueOf(pid), String.valueOf(beforeRestart.length));
Collections.addAll(commands, beforeRestart);
Collections.addAll(commands, String.valueOf(argc.getValue()));
Collections.addAll(commands, argv);
});
// Since the process ID is passed through the command line, we want to make sure that we don't exit before the "restarter"
// process has a chance to open the handle to our process, and that it doesn't wait for the termination of an unrelated
// process which happened to have the same process ID.
TimeoutUtil.sleep(500);
}
/**
* Get file descriptor.
*
* @return file descriptor.
*/
private synchronized int getSocketFd(SocketOption opt) throws IOException {
final int flag = opt.value();
final IntByReference fd = new IntByReference();
final IntByReference size_t = new IntByReference(Native.SIZE_T_SIZE);
final int rc = NativeLibrary.nn_getsockopt(this.fd,
OptionLevel.NN_SOL_SOCKET.value(),
flag, fd.getPointer(),
size_t.getPointer());
if (rc < 0) {
Nanomsg.handleError(rc);
}
return fd.getValue();
}
public static Process byName(String name) {
if (Platform.isWindows()) {
Tlhelp32.PROCESSENTRY32.ByReference entry = new Tlhelp32.PROCESSENTRY32.ByReference();
Pointer snapshot = Kernel32.CreateToolhelp32Snapshot(Tlhelp32.TH32CS_SNAPALL.intValue(), 0);
try {
while (Kernel32.Process32NextW(snapshot, entry)) {
String processName = Native.toString(entry.szExeFile);
if (name.equals(processName)) {
return byId(entry.th32ProcessID.intValue());
}
}
} finally {
Kernel32.CloseHandle(snapshot);
}
} else if (Platform.isMac() || Platform.isLinux()) {
return byId(Utils.exec("bash", "-c", "ps -A | grep -m1 \"" + name + "\" | awk '{print $1}'"));
} else {
throw new UnsupportedOperationException("Unknown operating system! (" + System.getProperty("os.name") + ")");
}
throw new IllegalStateException("Process '" + name + "' was not found. Are you sure its running?");
}
protected static synchronized void loadLibrary(UnixSyslogConfig config) throws SyslogRuntimeException {
if (!OSDetectUtility.isUnix()) {
throw new SyslogRuntimeException("UnixSyslog not supported on non-Unix platforms");
}
if (libraryInstance == null) {
libraryInstance = (CLibrary) Native.loadLibrary(config.getLibrary(), CLibrary.class);
}
}
private static CLibrary init() {
if (Platform.isMac() || Platform.isOpenBSD()) {
return (CLibrary) Native.loadLibrary("c", BSDCLibrary.class);
} else if (Platform.isFreeBSD()) {
return (CLibrary) Native.loadLibrary("c", FreeBSDCLibrary.class);
} else if (Platform.isSolaris()) {
return (CLibrary) Native.loadLibrary("c", SolarisCLibrary.class);
} else if (Platform.isLinux()) {
return (CLibrary) Native.loadLibrary("c", LinuxCLibrary.class);
} else {
return (CLibrary) Native.loadLibrary("c", CLibrary.class);
}
}
public void setValue(SizeT value) {
Pointer p = getPointer();
if (Native.SIZE_T_SIZE == 8) {
p.setLong(0, value.longValue());
} else {
p.setInt(0, value.intValue());
}
}
protected static synchronized void loadLibrary(UnixSyslogConfig config) throws SyslogRuntimeException {
if (!OSDetectUtility.isUnix()) {
throw new SyslogRuntimeException("UnixSyslog not supported on non-Unix platforms");
}
if (libraryInstance == null) {
libraryInstance = (CLibrary) Native.loadLibrary(config.getLibrary(),CLibrary.class);
}
}
/**
* Get a registry REG_EXPAND_SZ value.
*
* @param root Root key.
* @param key Registry path.
* @param value Name of the value to retrieve.
* @return String value.
*/
public static String registryGetExpandableStringValue(HKEY root, String key, String value) {
HKEYByReference phkKey = new HKEYByReference();
int rc = Advapi32.INSTANCE.RegOpenKeyEx(root, key, 0, WinNT.KEY_READ | WinNT.KEY_WOW64_32KEY, phkKey);
if (rc != W32Errors.ERROR_SUCCESS) {
throw new Win32Exception(rc);
}
try {
IntByReference lpcbData = new IntByReference();
IntByReference lpType = new IntByReference();
rc = Advapi32.INSTANCE.RegQueryValueEx(
phkKey.getValue(), value, 0, lpType, (char[]) null, lpcbData);
if (rc != W32Errors.ERROR_SUCCESS && rc != W32Errors.ERROR_INSUFFICIENT_BUFFER) {
throw new Win32Exception(rc);
}
if (lpType.getValue() != WinNT.REG_EXPAND_SZ) {
throw new RuntimeException("Unexpected registry type " + lpType.getValue() + ", expected REG_SZ");
}
char[] data = new char[lpcbData.getValue()];
rc = Advapi32.INSTANCE.RegQueryValueEx(
phkKey.getValue(), value, 0, lpType, data, lpcbData);
if (rc != W32Errors.ERROR_SUCCESS && rc != W32Errors.ERROR_INSUFFICIENT_BUFFER) {
throw new Win32Exception(rc);
}
return Native.toString(data);
} finally {
rc = Advapi32.INSTANCE.RegCloseKey(phkKey.getValue());
if (rc != W32Errors.ERROR_SUCCESS) {
throw new Win32Exception(rc);
}
}
}
private static CudaLibrary loadLibrary() {
try {
if (System.getProperty("os.name").startsWith("Win")) {
String path = System.getenv("PATH");
if (path == null) {
return null;
}
Pattern p = Pattern.compile("cudart64_\\d+\\.dll");
String[] searchPath = path.split(";");
for (String item : searchPath) {
File dir = new File(item);
File[] files = dir.listFiles(n -> p.matcher(n.getName()).matches());
if (files != null && files.length > 0) {
String fileName = files[0].getName();
String cudaRt = fileName.substring(0, fileName.length() - 4);
logger.debug("Found cudart: {}", files[0].getAbsolutePath());
return Native.load(cudaRt, CudaLibrary.class);
}
}
logger.debug("No cudart library found in path.");
return null;
}
return Native.load("cudart", CudaLibrary.class);
} catch (UnsatisfiedLinkError e) {
logger.debug("cudart library not found.");
logger.trace("", e);
return null;
}
}
/**
* Set a string value in registry.
*
* @param hKey Parent key.
* @param name Value name.
* @param value Value to write to registry.
*/
public static void registrySetStringValue(HKEY hKey, String name, String value) {
char[] data = Native.toCharArray(value);
int rc = Advapi32.INSTANCE.RegSetValueEx(hKey, name, 0, WinNT.REG_SZ,
data, data.length * Native.WCHAR_SIZE);
if (rc != W32Errors.ERROR_SUCCESS) {
throw new Win32Exception(rc);
}
}
/**
* Constructs a {@link Memory} buffer PointerArray given the Pointers to include in it.
*
* @param arg the pointers to include in the array
*/
public PointerArray(Pointer... arg) {
super(Native.POINTER_SIZE * (arg.length + 1));
length = arg.length;
for (int i = 0; i < arg.length; i++) {
setPointer(i * Native.POINTER_SIZE, arg[i]);
}
setPointer(Native.POINTER_SIZE * arg.length, null);
}
private static String shortPath(String path) {
if (path.contains(" ")) {
// On the way from Runtime.exec() to CreateProcess(), a command line goes through couple rounds of merging and splitting
// which breaks paths containing a sequence of two or more spaces.
// Conversion to a short format is an ugly hack allowing to open such paths in Explorer.
char[] result = new char[WinDef.MAX_PATH];
if (Kernel32.INSTANCE.GetShortPathName(path, result, result.length) <= result.length) {
return Native.toString(result);
}
}
return path;
}
JnaUnixMediatorImpl() throws Exception {
if (SystemInfo.isLinux) {
if ("arm".equals(SystemInfo.OS_ARCH)) {
if (SystemInfo.is32Bit) {
myOffsets = LINUX_ARM;
}
else {
throw new IllegalStateException("AArch64 architecture is not supported");
}
}
else if ("ppc".equals(SystemInfo.OS_ARCH)) {
myOffsets = SystemInfo.is32Bit ? LNX_PPC32 : LNX_PPC64;
}
else {
myOffsets = SystemInfo.is32Bit ? LINUX_32 : LINUX_64;
}
}
else if (SystemInfo.isMac | SystemInfo.isFreeBSD) {
myOffsets = SystemInfo.is32Bit ? BSD_32 : BSD_64;
}
else if (SystemInfo.isSolaris) {
myOffsets = SystemInfo.is32Bit ? SUN_OS_32 : SUN_OS_64;
}
else {
throw new IllegalStateException("Unsupported OS/arch: " + SystemInfo.OS_NAME + "/" + SystemInfo.OS_ARCH);
}
myLibC = (LibC)Native.loadLibrary("c", LibC.class);
myUid = myLibC.getuid();
myGid = myLibC.getgid();
}
public static Pointer toPointer(int[] arr) {
ByteBuffer bb = ByteBuffer.allocateDirect(arr.length * 4);
bb.order(ByteOrder.nativeOrder());
bb.asIntBuffer().put(arr);
bb.rewind();
return Native.getDirectBufferPointer(bb);
}
/**
* Get a registry REG_SZ value.
*
* @param root Root key.
* @param key Registry path.
* @param value Name of the value to retrieve.
* @return String value.
*/
public static String registryGetStringValue(HKEY root, String key, String value) {
HKEYByReference phkKey = new HKEYByReference();
int rc = Advapi32.INSTANCE.RegOpenKeyEx(root, key, 0, WinNT.KEY_READ | WinNT.KEY_WOW64_32KEY, phkKey);
if (rc != W32Errors.ERROR_SUCCESS) {
throw new Win32Exception(rc);
}
try {
IntByReference lpcbData = new IntByReference();
IntByReference lpType = new IntByReference();
rc = Advapi32.INSTANCE.RegQueryValueEx(
phkKey.getValue(), value, 0, lpType, (char[]) null, lpcbData);
if (rc != W32Errors.ERROR_SUCCESS && rc != W32Errors.ERROR_INSUFFICIENT_BUFFER) {
throw new Win32Exception(rc);
}
if (lpType.getValue() != WinNT.REG_SZ) {
throw new RuntimeException("Unexpected registry type " + lpType.getValue() + ", expected REG_SZ");
}
char[] data = new char[lpcbData.getValue()];
rc = Advapi32.INSTANCE.RegQueryValueEx(
phkKey.getValue(), value, 0, lpType, data, lpcbData);
if (rc != W32Errors.ERROR_SUCCESS && rc != W32Errors.ERROR_INSUFFICIENT_BUFFER) {
throw new Win32Exception(rc);
}
return Native.toString(data);
} finally {
rc = Advapi32.INSTANCE.RegCloseKey(phkKey.getValue());
if (rc != W32Errors.ERROR_SUCCESS) {
throw new Win32Exception(rc);
}
}
}
static WkHtmlToPdf load() {
if ((!tmpDir.exists() && !tmpDir.mkdirs())) {
throw new IllegalStateException("htmltopdf temporary directory cannot be created");
}
if (!tmpDir.canWrite()) {
throw new IllegalStateException("htmltopdf temporary directory is not writable");
}
File libraryFile = new File(tmpDir, getLibraryResource());
if (!libraryFile.exists()) {
try {
File dirPath = libraryFile.getParentFile();
if (!dirPath.exists() && !dirPath.mkdirs()) {
throw new IllegalStateException("unable to create directories for native library");
}
try (InputStream in = WkHtmlToPdfLoader.class.getResourceAsStream(getLibraryResource())) {
Files.copy(in, libraryFile.toPath(), StandardCopyOption.REPLACE_EXISTING);
}
} catch (IOException e) {
throw new RuntimeException(e);
}
}
WkHtmlToPdf instance = (WkHtmlToPdf)Native.loadLibrary(libraryFile.getAbsolutePath(), WkHtmlToPdf.class);
instance.wkhtmltopdf_init(0);
return instance;
}
private static LibC loadLibC() {
try {
return (LibC) Native.loadLibrary("c", LibC.class);
} catch (LinkageError e) {
LOGGER.debug("Unable to load LibC library. Continuing with fallback filesystem implementations.");
return null;
}
}
public NativeGNULinuxTerminal(
InputStream terminalInput,
OutputStream terminalOutput,
Charset terminalCharset,
CtrlCBehaviour terminalCtrlCBehaviour) throws IOException {
super(terminalInput,
terminalOutput,
terminalCharset,
terminalCtrlCBehaviour);
this.libc = (PosixLibC) Native.loadLibrary("c", PosixLibC.class);
this.savedTerminalState = null;
}
@Benchmark
public void memory_get_set_pointer() {
long p = Native.malloc(1000);
Pointer pointer = new Pointer(p);
pointer.setByte(10, (byte) 10);
byte b = pointer.getByte(10);
Native.free(p);
}
@Override
public MemoryBuffer read(Pointer address, int size, MemoryBuffer buffer) {
if (Kernel32.ReadProcessMemory(pointer(), address, buffer, size, 0) == 0) {
throw new Win32Exception(Native.getLastError());
}
return buffer;
}
static void tryVirtualLock() {
JNAKernel32Library kernel = JNAKernel32Library.getInstance();
Pointer process = null;
try {
process = kernel.GetCurrentProcess();
// By default, Windows limits the number of pages that can be locked.
// Thus, we need to first increase the working set size of the JVM by
// the amount of memory we wish to lock, plus a small overhead (1MB).
SizeT size = new SizeT(JvmInfo.jvmInfo().getMem().getHeapInit().getBytes() + (1024 * 1024));
if (!kernel.SetProcessWorkingSetSize(process, size, size)) {
LOGGER.warn("Unable to lock JVM memory. Failed to set working set size. Error code {}", Native.getLastError());
} else {
JNAKernel32Library.MemoryBasicInformation memInfo = new JNAKernel32Library.MemoryBasicInformation();
long address = 0;
while (kernel.VirtualQueryEx(process, new Pointer(address), memInfo, memInfo.size()) != 0) {
boolean lockable = memInfo.State.longValue() == JNAKernel32Library.MEM_COMMIT
&& (memInfo.Protect.longValue() & JNAKernel32Library.PAGE_NOACCESS) != JNAKernel32Library.PAGE_NOACCESS
&& (memInfo.Protect.longValue() & JNAKernel32Library.PAGE_GUARD) != JNAKernel32Library.PAGE_GUARD;
if (lockable) {
kernel.VirtualLock(memInfo.BaseAddress, new SizeT(memInfo.RegionSize.longValue()));
}
// Move to the next region
address += memInfo.RegionSize.longValue();
}
LOCAL_MLOCKALL = true;
}
} catch (UnsatisfiedLinkError e) {
// this will have already been logged by Kernel32Library, no need to repeat it
} finally {
if (process != null) {
kernel.CloseHandle(process);
}
}
}