[jffi-next] 10/24: Add wrappers around jni RegisterNatives and UnregisterNatives
Tim Potter
tpot-guest at moszumanska.debian.org
Wed Mar 4 04:51:30 UTC 2015
This is an automated email from the git hooks/post-receive script.
tpot-guest pushed a commit to tag 0.6.5
in repository jffi-next.
commit b85e6e97be29ff3fd27e66292e6ab814e9fbe972
Author: Wayne Meissner <wmeissner at gmail.com>
Date: Thu Dec 31 14:41:01 2009 +1000
Add wrappers around jni RegisterNatives and UnregisterNatives
---
src/com/kenai/jffi/Foreign.java | 12 ++++
src/com/kenai/jffi/NativeMethod.java | 67 ++++++++++++++++++++
src/com/kenai/jffi/NativeMethods.java | 114 ++++++++++++++++++++++++++++++++++
3 files changed, 193 insertions(+)
diff --git a/src/com/kenai/jffi/Foreign.java b/src/com/kenai/jffi/Foreign.java
index e4729a6..7b15e75 100644
--- a/src/com/kenai/jffi/Foreign.java
+++ b/src/com/kenai/jffi/Foreign.java
@@ -137,6 +137,18 @@ final class Foreign {
public static final int MEM_4MB_PAGES = 0x80000000;
/*
+ * possible return values for JNI functions.
+ */
+
+ public static final int JNI_OK = 0; /* success */
+ public static final int JNI_ERR = (-1); /* unknown error */
+ public static final int JNI_EDETACHED = (-2); /* thread detached from the VM */
+ public static final int JNI_EVERSION = (-3); /* JNI version error */
+ public static final int JNI_ENOMEM = (-4); /* not enough memory */
+ public static final int JNI_EEXIST = (-5); /* VM already created */
+ public static final int JNI_EINVAL = (-6); /* invalid arguments */
+
+ /*
* Function flags
*/
/**
diff --git a/src/com/kenai/jffi/NativeMethod.java b/src/com/kenai/jffi/NativeMethod.java
new file mode 100644
index 0000000..310e10d
--- /dev/null
+++ b/src/com/kenai/jffi/NativeMethod.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2009 Wayne Meissner
+ *
+ * This file is part of jffi.
+ *
+ * This code is free software: you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License version 3 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * version 3 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with this work. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package com.kenai.jffi;
+
+/**
+ * Represents a native implementation of a method for a class
+ */
+public final class NativeMethod {
+ final long function;
+ final long name;
+ final long signature;
+
+ /**
+ * Creates a new native method wrapper.
+ *
+ * @param address The address of the native method.
+ * @param name The name of the java method.
+ * @param signature The java signature.
+ */
+ public NativeMethod(long address, String name, String signature) {
+ this.function = address;
+ this.name = nativeString(name);
+ this.signature = nativeString(signature);
+ }
+
+ private static final long nativeString(String s) {
+ byte[] bytes = s.getBytes();
+
+ long memory = MemoryIO.getInstance().allocateMemory(bytes.length + 1, false);
+ if (memory == 0L) {
+ throw new OutOfMemoryError("failed to allocate memory for string");
+ }
+
+ MemoryIO.getInstance().putZeroTerminatedByteArray(memory, bytes, 0, bytes.length);
+ return memory;
+ }
+
+ @Override
+ protected void finalize() throws Throwable {
+ try {
+ if (name != 0L) {
+ MemoryIO.getInstance().freeMemory(name);
+ }
+ if (signature != 0L) {
+ MemoryIO.getInstance().freeMemory(signature);
+ }
+ } finally {
+ super.finalize();
+ }
+ }
+}
diff --git a/src/com/kenai/jffi/NativeMethods.java b/src/com/kenai/jffi/NativeMethods.java
new file mode 100644
index 0000000..842f6da
--- /dev/null
+++ b/src/com/kenai/jffi/NativeMethods.java
@@ -0,0 +1,114 @@
+/*
+ * Copyright (C) 2009 Wayne Meissner
+ *
+ * This file is part of jffi.
+ *
+ * This code is free software: you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License version 3 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * version 3 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with this work. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package com.kenai.jffi;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.WeakHashMap;
+
+/**
+ * Utility class to register native methods on a class
+ */
+public final class NativeMethods {
+
+ /**
+ * Store a link from the class to the native method holder in a weak
+ * hash map, so as long as the class remains alive, the native memory for the
+ * structures remains alive.
+ *
+ * This doesn't seem to be neccessary on sun's jvm, but best do it to be safe.
+ */
+ private static final Map<Class, NativeMethods> registeredMethods
+ = new WeakHashMap<Class, NativeMethods>();
+
+ private final long memory;
+ private final List<NativeMethod> methods;
+
+ private NativeMethods(long memory, List<NativeMethod> methods) {
+ this.memory = memory;
+ this.methods = new ArrayList<NativeMethod>(methods);
+ }
+
+ /**
+ * Registers the native methods for a class.
+ *
+ * @param clazz The java class to register the native methods for.
+ * @param methods The list of methods to attach to the class.
+ */
+ public static synchronized final void register(Class clazz, List<NativeMethod> methods) {
+ final long ptrSize = Platform.getPlatform().addressSize() / 8;
+ final MemoryIO mm = MemoryIO.getInstance();
+
+ //
+ // Each JNINativeMethod struct is 3 pointers
+ // i.e.
+ // typedef struct {
+ // char *name;
+ // char *signature;
+ // void *fnPtr;
+ // } JNINativeMethod;
+
+ long memory = mm.allocateMemory(methods.size() * 3 * ptrSize, true);
+ if (memory == 0L) {
+ throw new OutOfMemoryError("could not allocate native memory");
+ }
+
+ NativeMethods nm = new NativeMethods(memory, methods);
+
+ long off = 0;
+ for (NativeMethod m : methods) {
+ mm.putAddress(memory + off, m.name); off += ptrSize;
+ mm.putAddress(memory + off, m.signature); off += ptrSize;
+ mm.putAddress(memory + off, m.function); off += ptrSize;
+ }
+
+ if (Foreign.getInstance().registerNatives(clazz, memory, methods.size()) != Foreign.JNI_OK) {
+ throw new RuntimeException("failed to register native methods");
+ }
+
+ registeredMethods.put(clazz, nm);
+ }
+
+ /**
+ * Removes all native method attachments for the specified class.
+ *
+ * @param clazz The class to unregister the native methods on.
+ */
+ public static synchronized final void unregister(Class clazz) {
+ if (!registeredMethods.containsKey(clazz)) {
+ throw new IllegalArgumentException("methods were not registered on class via NativeMethods.register");
+ }
+
+ if (Foreign.getInstance().unregisterNatives(clazz) != Foreign.JNI_OK) {
+ throw new RuntimeException("failed to unregister native methods");
+ }
+
+ registeredMethods.remove(clazz);
+ }
+
+ @Override
+ protected void finalize() throws Throwable {
+ try {
+ MemoryIO.getInstance().freeMemory(memory);
+ } finally {
+ super.finalize();
+ }
+ }
+}
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-java/jffi-next.git
More information about the pkg-java-commits
mailing list