[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