下面列出了怎么用com.sun.jna.NativeLibrary的API类实例代码及写法,或者点击链接到github查看源代码。
@Override public LKey addWatch(String path) throws IOException {
// what if the file doesn't exist?
int id = IMPL.inotify_add_watch(fd, path,
InotifyImpl.IN_CREATE | InotifyImpl.IN_MOVED_TO |
InotifyImpl.IN_DELETE | InotifyImpl.IN_MOVED_FROM |
InotifyImpl.IN_MODIFY | InotifyImpl.IN_ATTRIB);
//XXX handle error return value (-1)
LOG.log(Level.FINEST, "addWatch{0} res: {1}", new Object[]{path, id});
if (id <= 0) {
// 28 == EINOSPC
int errno = NativeLibrary.getInstance("c").getFunction("errno").getInt(0); // NOI18N
throw new IOException("addWatch on " + path + " errno: " + errno); // NOI18N
}
LKey newKey = map.get(id);
if (newKey == null) {
newKey = new LKey(id, path);
map.put(id, newKey);
}
return newKey;
}
private static NativeLibrary loadLibraryWithTiming(String name) {
String successName = String.format("mr4c.loadlib.%s.success", name);
String failureName = String.format("mr4c.loadlib.%s.failure", name);
StatsTimer timer = new StatsTimer(
MR4CStats.getClient(),
successName,
failureName
);
boolean success = false;
try {
NativeLibrary result = doLoadLibrary(name);
success = true;
return result;
} finally {
timer.done(success);
}
}
protected void loadNativeLibraries() {
s_log.info("Begin loading native libraries");
s_log.info("jna.library.path={}", System.getProperty("jna.library.path"));
s_log.info("jna.platform.library.path={}", System.getProperty("jna.platform.library.path"));
s_log.info("LD_LIBRARY_PATH={}", System.getenv("LD_LIBRARY_PATH"));
s_log.info("MR4C native library found at [{}]", Mr4cLibrary.JNA_NATIVE_LIB.getFile().getAbsolutePath());
String libName = getAlgorithmConfig().getArtifact();
s_log.info("Loading native algorithm library [{}]", libName);
m_lib = JnaUtils.loadLibrary(libName);
s_log.info("Native algorithm library found at [{}]", m_lib.getFile().getAbsolutePath());
for ( String name : getAlgorithmConfig().getExtras() ) {
s_log.info("Loading extra native library [{}]", name);
NativeLibrary lib = JnaUtils.loadLibrary(name);
s_log.info("Extra native library found at [{}]", lib.getFile().getAbsolutePath());
m_extras.add(lib);
}
s_log.info("End loading native libraries");
}
/**
* 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);
}
}
public synchronized static NativeLibrary loadLibrary(String name) {
NativeLibrary lib = s_loadedLibs.get(name);
if ( lib==null ) {
lib = loadLibraryWithTiming(name);
s_loadedLibs.put(name,lib);
}
return lib;
}
public Collection<File> getRequiredFiles() {
List<File> files = new ArrayList();
files.add(Mr4cLibrary.JNA_NATIVE_LIB.getFile());
files.add( m_lib.getFile());
for ( NativeLibrary lib : m_extras ) {
files.add(lib.getFile());
}
return files;
}
private void disposeImpl() {
final FbClientLibrary local = library;
if (local == null) {
return;
}
owner.disposing(this, new Runnable() {
@Override
public void run() {
library = null;
if (isNativeResourceShutdownDisabled()) return;
// only explicitly shutdown and dispose if native resource shutdown is not disabled
Logger logger = LoggerFactory.getLogger(FbClientResource.class);
try {
if (logger.isDebugEnabled()) logger.debug("Calling fb_shutdown on " + local);
local.fb_shutdown(0, 1);
} finally {
FbClientFeatureAccessHandler handler =
(FbClientFeatureAccessHandler) Proxy.getInvocationHandler(local);
NativeLibrary nativeLibrary = handler.getNativeLibrary();
if (logger.isDebugEnabled()) logger.debug("Disposing JNA native library " + nativeLibrary);
try {
nativeLibrary.dispose();
} catch (Throwable e) {
logger.error("Error disposing of " + nativeLibrary, e);
}
}
}
});
}
private FbClientFeatureAccessHandler(FbClientLibrary clientLibrary, NativeLibrary nativeLibrary,
Set<FbClientFeature> clientFeatures, InvocationHandler delegatedHandler) {
this.clientLibrary = clientLibrary;
this.nativeLibrary = nativeLibrary;
this.clientFeatures = clientFeatures;
this.delegatedHandler = delegatedHandler;
}
/**
* Creates a {@code FbClientLibrary} proxy implementing {@link FbClientFeatureAccess}.
*
* @param library
* The original {@code FbClientLibrary} proxy object
* @return New proxy for {@code library} that implements {@link FbClientFeatureAccess}
* @throws IllegalArgumentException
* if {@code library} is not a proxy with {@link Library.Handler} as its invocation handler
*/
static FbClientLibrary decorateWithFeatureAccess(FbClientLibrary library) {
Class<?> libraryClass = library.getClass();
if (!Proxy.isProxyClass(libraryClass)) {
throw new IllegalArgumentException(
"Could not decorate client library with FbClientFeatureAccess: not a proxy");
}
InvocationHandler ih = Proxy.getInvocationHandler(library);
if (!(ih instanceof Library.Handler)) {
throw new IllegalArgumentException("Could not decorate client library with FbClientFeatureAccess: "
+ "unexpected invocation handler type " + ih.getClass());
}
Library.Handler originalHandler = (Library.Handler) ih;
NativeLibrary nativeLibrary = originalHandler.getNativeLibrary();
Set<FbClientFeature> clientFeatures = determineClientFeatures(nativeLibrary);
InvocationHandler delegatedHandler = syncWrapIfNecessary(library, originalHandler);
FbClientFeatureAccessHandler fbClientFeatureAccessHandler =
new FbClientFeatureAccessHandler(library, nativeLibrary, clientFeatures, delegatedHandler);
Class<?> interfaceClass = originalHandler.getInterfaceClass();
ClassLoader loader = interfaceClass.getClassLoader();
Object proxy = Proxy.newProxyInstance(loader, new Class[] { interfaceClass, FbClientFeatureAccess.class },
fbClientFeatureAccessHandler);
return (FbClientLibrary) proxy;
}
private static Set<FbClientFeature> determineClientFeatures(NativeLibrary nativeLibrary) {
EnumSet<FbClientFeature> features = EnumSet.allOf(FbClientFeature.class);
for (FbClientFeature feature : FbClientFeature.values()) {
for (String methodName : feature.methodNames()) {
if (!hasMethod(nativeLibrary, methodName)) {
features.remove(feature);
break;
}
}
}
return features;
}
private static boolean hasMethod(NativeLibrary nativeLibrary, String methodName) {
try {
return nativeLibrary.getFunction(methodName) != null;
} catch (UnsatisfiedLinkError e) {
// not found
return false;
}
}
/**
* Contructor for the {@link EpanetWrapper}.
*
* <p>This also takes care to load the native library, if needed.
*
* @param lib the name of the library (ex. "epanet2_64bit").
* @param nativeLibPath the path in which to search the native library.
* If the native library is already in the java library path
* this is not needed and may be <code>null</code>
* @throws Exception if the library could not be loaded.
*/
public EpanetWrapper( String lib, String nativeLibPath ) throws Exception {
if (epanet == null) {
try {
if (nativeLibPath != null)
NativeLibrary.addSearchPath(lib, nativeLibPath);
epanet = (EpanetNativeFunctions) Native.loadLibrary(lib, EpanetNativeFunctions.class);
} catch (Exception e) {
throw new Exception("An error occurred while trying to load the epanet library.", e);
}
}
}
public static synchronized void init() {
NativeLibrary libcLibrary = NativeLibrary.getInstance(Platform.C_LIBRARY_NAME);
// We kill subprocesses by sending SIGINT to our process group; we want our subprocesses to die
// on SIGINT while we ourselves stay around. We can't just set SIGINT to SIG_IGN, because
// subprocesses would inherit the SIG_IGN signal disposition and be immune to the SIGINT we
// direct toward the process group. We need _some_ signal handler that does nothing --- i.e.,
// acts like SIG_IGN --- but that doesn't kill its host process. When we spawn a subprocess,
// the kernel replaces any signal handler that is not SIG_IGN with SIG_DFL, automatically
// creating the signal handler configuration we want.
//
// getpid might seem like a strange choice of signal handler, but consider the following:
//
// 1) on all supported ABIs, calling a function that returns int as if it returned void is
// harmless --- the return value is stuffed into a register (for example, EAX on x86
// 32-bit) that the caller ignores (EAX is caller-saved),
//
// 2) on all supported ABIs, calling a function with extra arguments is safe --- the callee
// ignores the extra arguments, which are passed either in caller-saved registers or in
// stack locations that the caller [1] cleans up upon return,
//
// 3) getpid is void(*)(int); signal handlers are void(*)(int), and
//
// 4) getpid is async-signal-safe according to POSIX.
//
// Therefore, it is safe to set getpid _as_ a signal handler. It does nothing, exactly as we
// want, and gets reset to SIG_DFL in subprocesses. If we were a C program, we'd just define a
// no-op function of the correct signature to use as a handler, but we're using JNA, and while
// JNA does have the ability to C function pointer to a Java function, it cannot create an
// async-signal-safe C function, since calls into Java are inherently signal-unsafe.
//
// [1] Win32 32-bit x86 stdcall is an exception to this general rule --- because the callee
// cleans up its stack --- but we don't run this code on Windows.
//
Libc.INSTANCE.signal(Libc.Constants.SIGINT, libcLibrary.getFunction("getpid"));
initialized = true;
}
public static void onWindows() {
// Windows taskbar fix: provideAppUserModelID
try {
NativeLibrary lib = NativeLibrary.getInstance("shell32");
Function function = lib.getFunction("SetCurrentProcessExplicitAppUserModelID");
Object[] args = {new WString(APPID)};
function.invokeInt(args);
} catch (Error e) {
return;
} catch (Exception x) {
return;
}
}
/**
* Returns the API instance used to call native Domino C API methods for 32 bit
*
* @return API
*/
public static INotesNativeAPIV901 get() {
NotesGC.ensureRunningInAutoGC();
if (NotesNativeAPI.m_initError!=null) {
if (NotesNativeAPI.m_initError instanceof RuntimeException)
throw (RuntimeException) NotesNativeAPI.m_initError;
else
throw new NotesError(0, "Error initializing Domino JNA API", NotesNativeAPI.m_initError);
}
if (m_instanceWithoutCrashLogging==null) {
m_instanceWithoutCrashLogging = AccessController.doPrivileged(new PrivilegedAction<INotesNativeAPIV901>() {
@Override
public INotesNativeAPIV901 run() {
Mode jnaMode = NotesNativeAPI.getActiveJNAMode();
Map<String,Object> libraryOptions = NotesNativeAPI.getLibraryOptions();
if (jnaMode==Mode.Direct) {
NativeLibrary library;
if (PlatformUtils.isWindows()) {
library = NativeLibrary.getInstance("nnotes", libraryOptions);
}
else {
library = NativeLibrary.getInstance("notes", libraryOptions);
}
Native.register(NotesNativeAPIV901.class, library);
NotesNativeAPIV901 instance = new NotesNativeAPIV901();
return instance;
}
else {
INotesNativeAPIV901 api;
if (PlatformUtils.isWindows()) {
api = Native.loadLibrary("nnotes", INotesNativeAPIV901.class, libraryOptions);
}
else {
api = Native.loadLibrary("notes", INotesNativeAPIV901.class, libraryOptions);
}
return api;
}
}
});
}
if (NotesGC.isLogCrashingThreadStacktrace()) {
if (m_instanceWithCrashLogging==null) {
m_instanceWithCrashLogging = NotesNativeAPI.wrapWithCrashStackLogging(INotesNativeAPIV901.class,
m_instanceWithoutCrashLogging);
}
return m_instanceWithCrashLogging;
}
else {
return m_instanceWithoutCrashLogging;
}
}
/**
* Returns the API instance used to call native Domino C API methods for 32 bit
*
* @return API
*/
public static INotesNativeAPI64V1000 get() {
NotesGC.ensureRunningInAutoGC();
if (NotesNativeAPI.m_initError!=null) {
if (NotesNativeAPI.m_initError instanceof RuntimeException)
throw (RuntimeException) NotesNativeAPI.m_initError;
else
throw new NotesError(0, "Error initializing Domino JNA API", NotesNativeAPI.m_initError);
}
if (m_instanceWithoutCrashLogging==null) {
m_instanceWithoutCrashLogging = AccessController.doPrivileged(new PrivilegedAction<INotesNativeAPI64V1000>() {
@Override
public INotesNativeAPI64V1000 run() {
Mode jnaMode = NotesNativeAPI.getActiveJNAMode();
Map<String,Object> libraryOptions = NotesNativeAPI.getLibraryOptions();
if (jnaMode==Mode.Direct) {
NativeLibrary library;
if (PlatformUtils.isWindows()) {
library = NativeLibrary.getInstance("nnotes", libraryOptions);
}
else {
library = NativeLibrary.getInstance("notes", libraryOptions);
}
Native.register(NotesNativeAPI64V1000.class, library);
NotesNativeAPI64V1000 instance = new NotesNativeAPI64V1000();
return instance;
}
else {
INotesNativeAPI64V1000 api;
if (PlatformUtils.isWindows()) {
api = Native.loadLibrary("nnotes", INotesNativeAPI64V1000.class, libraryOptions);
}
else {
api = Native.loadLibrary("notes", INotesNativeAPI64V1000.class, libraryOptions);
}
return api;
}
}
});
}
if (NotesGC.isLogCrashingThreadStacktrace()) {
if (m_instanceWithCrashLogging==null) {
m_instanceWithCrashLogging = NotesNativeAPI.wrapWithCrashStackLogging(INotesNativeAPI64V1000.class,
m_instanceWithoutCrashLogging);
}
return m_instanceWithCrashLogging;
}
else {
return m_instanceWithoutCrashLogging;
}
}
/**
* Returns the API instance used to call native Domino C API methods for 32 bit
*
* @return API
*/
public static INotesNativeAPI32V1000 get() {
NotesGC.ensureRunningInAutoGC();
if (NotesNativeAPI.m_initError!=null) {
if (NotesNativeAPI.m_initError instanceof RuntimeException)
throw (RuntimeException) NotesNativeAPI.m_initError;
else
throw new NotesError(0, "Error initializing Domino JNA API", NotesNativeAPI.m_initError);
}
if (m_instanceWithoutCrashLogging==null) {
m_instanceWithoutCrashLogging = AccessController.doPrivileged(new PrivilegedAction<INotesNativeAPI32V1000>() {
@Override
public INotesNativeAPI32V1000 run() {
Mode jnaMode = NotesNativeAPI.getActiveJNAMode();
Map<String,Object> libraryOptions = NotesNativeAPI.getLibraryOptions();
if (jnaMode==Mode.Direct) {
NativeLibrary library;
if (PlatformUtils.isWindows()) {
library = NativeLibrary.getInstance("nnotes", libraryOptions);
}
else {
library = NativeLibrary.getInstance("notes", libraryOptions);
}
Native.register(NotesNativeAPI32V1000.class, library);
NotesNativeAPI32V1000 instance = new NotesNativeAPI32V1000();
return instance;
}
else {
INotesNativeAPI32V1000 api;
if (PlatformUtils.isWindows()) {
api = Native.loadLibrary("nnotes", INotesNativeAPI32V1000.class, libraryOptions);
}
else {
api = Native.loadLibrary("notes", INotesNativeAPI32V1000.class, libraryOptions);
}
return api;
}
}
});
}
if (NotesGC.isLogCrashingThreadStacktrace()) {
if (m_instanceWithCrashLogging==null) {
m_instanceWithCrashLogging = NotesNativeAPI.wrapWithCrashStackLogging(INotesNativeAPI32V1000.class,
m_instanceWithoutCrashLogging);
}
return m_instanceWithCrashLogging;
}
else {
return m_instanceWithoutCrashLogging;
}
}
private static NativeLibrary doLoadLibrary(String name) {
return NativeLibrary.getInstance(name);
}
NativeLibrary getNativeLibrary() {
return nativeLibrary;
}
private static void load(String name) {
NativeLibrary library = NativeLibrary.getInstance(name, LibGmp.class.getClassLoader());
Native.register(LibGmp.class, library);
Native.register(SIZE_T_CLASS, library);
}
@Override
public String getFunctionName(NativeLibrary lib, Method method) {
// MediaInfo_New(), MediaInfo_Open() ...
return "MediaInfo_" + method.getName();
}
@Override
public String getFunctionName(NativeLibrary nl, Method method) {
String result = translations.get(method.getName());
return result == null ? method.getName() : result;
}