【JAVA实用工具】JNA-通过它调用C++的方法,比JNI方便很多访问网站需要代理,所以把它COPY出来备忘
jna.library.path?system property to the path to your target library. This property is similar to?java.library.path?but only applies to libraries loaded by JNA.Library?interface.Following is an example of mapping for the Windows kernel32 library.
package com.sun.jna.examples.win32; import com.sun.jna.*; // kernel32.dll uses the __stdcall calling convention (check the function // declaration for "WINAPI" or "PASCAL"), so extend StdCallLibrary // Most C libraries will just extend com.sun.jna.Library, public interface Kernel32 extends StdCallLibrary { // Method declarations, constant and structure definitions go here }
Native.loadLibrary(Class)?method, providing the native library interface you defined in step (5).Kernel32 INSTANCE = (Kernel32) Native.loadLibrary("kernel32", Kernel32.class); // Optional: wraps every call to the native library in a // synchronized block, limiting native calls to one at a time Kernel32 SYNC_INSTANCE = (Kernel32) Native.synchronizedLibrary(INSTANCE);
Map?of options may be provided as the third argument to?loadLibrary?to customize the library behavior; some of these options are explained in more detail below. The SYNC_INSTANCE is also optional; use it if you need to ensure that your native library has only one call to it at a time.Structure?and add public fields (which may include arrays or nested structures).public static class SYSTEMTIME extends Structure { public short wYear; public short wMonth; public short wDayOfWeek; public short wDay; public short wHour; public short wMinute; public short wSecond; public short wMilliseconds; } void GetSystemTime(SYSTEMTIME result);
Kernel32 lib = Kernel32.INSTANCE; SYSTEMTIME time = new SYSTEMTIME(); lib.GetSystemTime(time); System.out.println("Today's integer value is " + time.wDay);
Native.register(String)?in the class static initializer with your library's name. See?JNA direct mapping?for an example.?
If the C header files for your library are available, you can auto-generate a library mapping by using Olivier Chafik's excellent?JNAerator?utility. This is especially useful if your library uses long or complicated structures where translating by hand can be error-prone.See the?JavaDoc overview?for more detailed information about JNA usage.
Top
Native TypeSizeJava TypeCommon Windows Typeschar8-bit integerbyteBYTE, TCHARshort16-bit integershortWORDwchar_t16/32-bit charactercharTCHARint32-bit integerintDWORDintboolean valuebooleanBOOLlong32/64-bit integerNativeLongLONGlong long64-bit integerlong__int64float32-bit FPfloatUnsigned types use the same mappings as signed types. C enums are usually interchangeable with "int". A more comprehensive list of mappings may be found?here.
double64-bit FPdouble
char*C stringStringLPTCSTRvoid*pointerPointerLPVOID, HANDLE, LPXXX
Top
structs) are represented by their corresponding Java types. For example:// Original C declarations void fill_buffer(int *buf, int len); void fill_buffer(int buf[], int len); // same thing with array syntax // Equivalent JNA mapping void fill_buffer(int[] buf, int len);
NOTE: if the parameter is to be used by the native function outside the scope of the function call, you?must?useMemory?or an NIO Buffer. The memory provided by a Java primitive array will only be valid for use by the native code for the duration of the function call.
Arrays of C strings (the?char* argv[]?to the C?main, for example), may be represented by?String[]?in Java code. JNA will pass an equivalent array with a NULL final element.
Top
struct, a Java?Structure?should be used. If the?struct?is passed or returned by value, you need only make?minor modifications?to the parameter or return type class declaration.Typically you define a?public static?class derived from?Structure?within your library interface definition. This allows the structure to share any options (like custom type mapping) defined for the library interface.
If a function requires an array of?struct?(allocated contiguously in memory), a Java?Structure[]?may be used. When passing in an array of?Structure, it is not necessary to initialize the array elements (the function call will allocate, zero memory, and assign the elements for you). If you?do?need to initialize the array, you should use theStructure.toArray?method to obtain an array of?Structure?elements contiguous in memory, which you can then initialize as needed.
Unions are generally interchangeable with?Structures, but require that you indicate which union field is active with the?setType?method before it can be properly passed to a function call.
Top
ByReference?types to capture the returned value, or subclass your own. For example:Alternatively, you could use a Java array with a single element of the desired type, but the?// Original C declaration void allocate_buffer(char **bufp, int* lenp); // Equivalent JNA mapping void allocate_buffer(PointerByReference bufp, IntByReference lenp); // Usage PointerByReference pref = new PointerByReference(); IntByReference iref = new IntByReference(); lib.allocate_buffer(pref, iref); Pointer p = pref.getValue(); byte[] buffer = p.getByteArray(0, iref.getValue());
ByReferenceconvention better conveys the intent of the code.The?Pointer?class provides a number of accessor methods in addition to?getByteArray()?which effectively function as a typecast onto the memory.
Type-safe pointers may be declared by deriving from the?PointerType?class.
Top
BOOL?type. A?TypeMapper?instance is passed as the value for the?TYPE_MAPPER?key in the options map passed to?Native.loadLibrary.Alternatively, user-defined types may implement the?NativeMapped?interface, which determines conversion to and from native types on a class-by-class basis.
You may also customize the mapping of Java method names to the corresponding native function name. TheStdCallFunctionMapper?is one implementation which automatically generates?stdcall-decorated function names from a Java interface method signature. The mapper should be passed as the value for theOPTION_FUNCTION_MAPPER?key in the options map passed to the?Native.loadLibrary?call.
Refer to?this table in the overview?for a complete list of built-in type mappings.
Top
callbackmethod (or defines a single method of arbitrary name). Callbacks are implemented by wrapping a Java object method in a little bit of C glue code. The simplest usage resembles using anonymous inner classes to register event listeners. Following is an example of callback usage:Here is a more involved example, using the w32 APIs to enumerate all native windows:// Original C declarations typedef void (*sig_t)(int); sig_t signal(sig_t); // Equivalent JNA mappings public interface CLibrary extends Library { int SIGUSR1 = 30; interface sig_t extends Callback { void invoke(int signal); } sig_t signal(int sig, sig_t fn); int raise(int sig); } ... CLibrary lib = (CLibrary)Native.loadLibrary("c", CLibrary.class); // WARNING: you must keep a reference to the callback object // until you deregister the callback; if the callback object // is garbage-collected, the native callback invocation will // probably crash. CLibrary.sig_t fn = new CLibrary.sig_t() { public void invoke(int sig) { System.out.println("signal " + sig + " was raised"); } }; CLibrary.sig_t old_handler = lib.signal(CLibrary.SIGUSR1, fn); lib.raise(CLibrary.SIGUSR1); ...
If your callback needs to live beyond the method invocation where it is used, make sure you keep a reference to it or the native code will call back to an empty stub after the callback object is garbage collected.// Original C declarations typedef int (__stdcall *WNDENUMPROC)(void*,void*); int __stdcall EnumWindows(WNDENUMPROC,void*); // Equivalent JNA mappings public interface User32 extends StdCallLibrary { interface WNDENUMPROC extends StdCallCallback { boolean callback(Pointer hWnd, Pointer arg); } boolean EnumWindows(WNDENUMPROC lpEnumFunc, Pointer arg); } ... User32 user32 = User32.INSTANCE; user32.EnumWindows(new WNDENUMPROC() { int count; public boolean callback(Pointer hWnd, Pointer userData) { System.out.println("Found window " + hWnd + ", total " + ++count); return true; } }, null);
Proxy wrappers are automatically generated for function pointers found within structs initialized by native code. This facilitates calling those functions from Java.
Top
Here's a brief example of using JNA from JRuby:
require 'java' module Libc @@lib = com.sun.jna.NativeLibrary.getInstance("c") @@ptr_funcs = [ 'fopen', 'malloc', 'calloc' ] def self.method_missing(meth, *args) if @@ptr_funcs.include?(meth.to_s) @@lib.getFunction(meth.to_s).invokePointer(args.to_java) else @@lib.getFunction(meth.to_s).invokeInt(args.to_java) end end O_RDONLY = 0 O_WRONLY = 1 O_RDWR = 2 end Libc.puts("puts from libc") Libc.printf("Hello %s, from printf\n", "World") file = Libc.open("/dev/stdout", 1, Libc::O_WRONLY) n = Libc.write(file, "Test\n", 5) puts "Wrote #{n} bytes via Libc" path = "/dev/stdout" fp = Libc.fopen(path, "w+") Libc.fprintf(fp, "fprintf to %s via stdio\n", path) Libc.fflush(fp) Libc.fclose(fp)
Top
JNA includes?platform.jar?that has cross-platform mappings and mappings for a number of commonly used platform functions, including a large number of Win32 mappings as well as a set of utility classes that simplify native access. The code is tested and the utility interfaces ensure that native memory management is taken care of correctly.
Before you map your own functions, check the?platform package documentation?for an already mapped one.
Platform-specific structures are mapped by header. For example,?ShlObj.h?structures can be found incom.sun.jna.platform.win32.ShlObj. Platform functions are mapped by library. For example,?Advapi32.dllfunctions can be found in?com.sun.jna.platform.win32.Advapi32. Simplified interfaces (wrappers) forAdvapi32.dll?functions can be found in?com.sun.jna.platform.win32.Advapi32Util.
Cross-platform functions and structures are implemented in?com.sun.jna.platform. These currently include the following.
FileMonitor: a cross-platform file system watcherFileUtils: a cross-platform set of file-related functions, such as move to the recycle binKeyboardUtils: a cross-platform set of keyboard functions, such as finding out whether a key is pressedWindowUtils: a cross-platform set of window functions, providing non-rectangular shaped and transparent windows