

![]() | Start a set with this search |
![]() | Include this search in one of my sets |
![]() | Exclude this search from one of my sets |
![]() | Permalink to these results Paste this link in email or IM: |
| Atom feed for tracking future search results Paste this URL into your reader: |
3 messages in net.java.dev.jna.usersRe: [jna-users] loading dynamic libra...| From | Sent On | Attachments |
|---|---|---|
| Filippo Carone | Dec 12, 2008 2:36 pm | .patch |
| Timothy Wall | Dec 13, 2008 6:20 am | |
| Filippo Carone | Dec 14, 2008 7:37 am |

![]() | Permalink for this message Paste this link in email or IM: |
![]() | Permalink for this thread Paste this link in email or IM: |
| Atom feed for this thread Paste this URL into your reader: |
| Subject: | Re: [jna-users] loading dynamic libraries in the global namespace | Actions... |
|---|---|---|
| From: | Timothy Wall (twal...@dev.java.net) | |
| Date: | Dec 13, 2008 6:20:36 am | |
| List: | net.java.dev.jna.users | |
OSX/BSD has RTLD_GLOBAL as the default, linux is undefined.
On Dec 12, 2008, at 5:37 PM, Filippo Carone wrote:
Hi, the attached patch allows users to specify if a given native library should be loaded in the global namespace.
Setting to Boolean.TRUE the Library.OPTION_DLOPEN_GLOBAL option in the options map argument given to Native.loadLibrary, will make jna to dlopen the library with the RTLD_GLOBAL option. For example:
Map options = new HashMap() { { put(Library.OPTION_DLOPEN_GLOBAL, Boolean.TRUE); } };
LibVlc INSTANCE = (LibVlc) Native.loadLibrary(Platform.isWindows()? "libvlc" : "vlc", LibVlc.class, options);
will make libvlc available in the global namespace of the java process, and so suitable for symbols resolution of shared objects loaded later (plugins for example).
Cheers, Filippo Index: jnalib/native/dispatch.c =================================================================== --- jnalib/native/dispatch.c (revision 744) +++ jnalib/native/dispatch.c (working copy) @@ -63,6 +63,7 @@ #define LIBNAME2CSTR(ENV,JSTR) newCString(ENV,JSTR) #endif #define LOAD_LIBRARY(NAME) dlopen(NAME, RTLD_LAZY) +#define LOAD_LIBRARY_GLOBAL(NAME) dlopen(NAME, RTLD_LAZY|RTLD_GLOBAL) #define LOAD_ERROR(BUF,LEN) (snprintf(BUF, LEN, "%s", dlerror()), BUF) #define FREE_LIBRARY(HANDLE) dlclose(HANDLE) #define FIND_ENTRY(HANDLE, NAME) dlsym(HANDLE, NAME) @@ -634,15 +635,20 @@ /* * Class: com_sun_jna_NativeLibrary * Method: open - * Signature: (Ljava/lang/String;)J + * Signature: (Ljava/lang/String;Z)J */ JNIEXPORT jlong JNICALL -Java_com_sun_jna_NativeLibrary_open(JNIEnv *env, jclass cls, jstring lib){ +Java_com_sun_jna_NativeLibrary_open(JNIEnv *env, jclass cls, jstring lib, jboolean global){ void *handle = NULL; LIBNAMETYPE libname = NULL;
if ((libname = LIBNAME2CSTR(env, lib)) != NULL) { - handle = (void *)LOAD_LIBRARY(libname); + if (!global) { + handle = (void *)LOAD_LIBRARY(libname); + } + else { + handle = (void *)LOAD_LIBRARY_GLOBAL(libname); + } if (!handle) { char buf[1024]; throwByName(env, EUnsatisfiedLink, LOAD_ERROR(buf, sizeof(buf))); Index: jnalib/src/com/sun/jna/NativeLibrary.java =================================================================== --- jnalib/src/com/sun/jna/NativeLibrary.java (revision 744) +++ jnalib/src/com/sun/jna/NativeLibrary.java (working copy) @@ -74,7 +74,7 @@ } }
- private static NativeLibrary loadLibrary(String libraryName) { + private static NativeLibrary loadLibrary(String libraryName, boolean global) { List searchPath = new LinkedList();
// Append web start path, if available. Note that this does not @@ -103,7 +103,7 @@ // if it cannot find the library. // try { - handle = open(libraryPath); + handle = open(libraryPath, global); } catch(UnsatisfiedLinkError e) { // Add the system paths back for all fallback searching @@ -112,7 +112,7 @@ try { if (handle == 0) { libraryPath = findLibraryPath(libraryName, searchPath); - handle = open(libraryPath); + handle = open(libraryPath, global); } } catch(UnsatisfiedLinkError e) { @@ -122,7 +122,7 @@ // libraryPath = matchLibrary(libraryName, searchPath); if (libraryPath != null) { - try { handle = open(libraryPath); } + try { handle = open(libraryPath, global); } catch(UnsatisfiedLinkError e2) { e = e2; } } } @@ -131,14 +131,14 @@ libraryPath = "/System/Library/Frameworks/" + libraryName + ".framework/" + libraryName; if (new File(libraryPath).exists()) { - try { handle = open(libraryPath); } + try { handle = open(libraryPath, global); } catch(UnsatisfiedLinkError e2) { e = e2; } } } // Try the same library with a "lib" prefix else if (Platform.isWindows()) { libraryPath = findLibraryPath("lib" + libraryName, searchPath); - try { handle = open(libraryPath); } + try { handle = open(libraryPath, global); } catch(UnsatisfiedLinkError e2) { e = e2; } } if (handle == 0) { @@ -185,7 +185,7 @@ WeakReference ref = (WeakReference)libraries.get(libraryName); NativeLibrary library = ref != null ? (NativeLibrary)ref.get() : null; if (library == null) { - library = loadLibrary(libraryName); + library = loadLibrary(libraryName, false); ref = new WeakReference(library); libraries.put(library.getName(), ref); libraries.put(library.getFile().getAbsolutePath(), ref); @@ -194,7 +194,43 @@ return library; } } + + /** + * Returns an instance of NativeLibrary for the specified name. + * The library is loaded if not already loaded. If already loaded, the + * existing instance is returned.<p> + * More than one name may map to the same NativeLibrary instance; only + * a single instance will be provided for any given unique file path. + * + * @param libraryName The library name to load. + * This can be short form (e.g. "c"), + * an explicit version (e.g. "libc.so.6"), or + * the full path to the library (e.g. "/lib/libc.so.6"). + * @param global If true, will load the library in the global namespace, otherwise + * the library is loaded in the local namespace (as the default behaviour). + */ + public static final NativeLibrary getInstance(String libraryName, boolean global) { + if (!global) + { + return getInstance(libraryName); + } + if (libraryName == null) + throw new NullPointerException("Library name may not be null");
+ synchronized (libraries) { + WeakReference ref = (WeakReference)libraries.get(libraryName); + NativeLibrary library = ref != null ? (NativeLibrary)ref.get() : null; + if (library == null) { + library = loadLibrary(libraryName, global); + ref = new WeakReference(library); + libraries.put(library.getName(), ref); + libraries.put(library.getFile().getAbsolutePath(), ref); + libraries.put(library.getFile().getName(), ref); + } + return library; + } + } + /** * Add a path to search for the specified library, ahead of any system paths * @@ -470,7 +506,7 @@ return v; }
- private static native long open(String name); + private static native long open(String name, boolean global); private static native void close(long handle); private static native long findSymbol(long handle, String name); static { Index: jnalib/src/com/sun/jna/Library.java =================================================================== --- jnalib/src/com/sun/jna/Library.java (revision 744) +++ jnalib/src/com/sun/jna/Library.java (working copy) @@ -74,6 +74,10 @@ * be one of the predefined alignment types in {@link Structure}. */ String OPTION_STRUCTURE_ALIGNMENT = "structure-alignment"; + /** Option key for loading the library in the global namespace, specifing + * RTLD_GLOBAL option for dlopen() native call. + */ + String OPTION_DLOPEN_GLOBAL = "dlopen-global"; static class Handler implements InvocationHandler {
static final Method OBJECT_TOSTRING; @@ -119,8 +123,15 @@ throw new IllegalArgumentException("Invalid library name \"" + libname + "\""); } - - this.nativeLibrary = NativeLibrary.getInstance(libname); + Boolean dlopenGlobal = (Boolean)options.get(OPTION_DLOPEN_GLOBAL); + if (Boolean.TRUE.equals(dlopenGlobal)) + { + this.nativeLibrary = NativeLibrary.getInstance(libname, true); + } + else + { + this.nativeLibrary = NativeLibrary.getInstance(libname); + } this.interfaceClass = interfaceClass; this.options = options; this.callingConvention = Index: jnalib/build.xml =================================================================== --- jnalib/build.xml (revision 744) +++ jnalib/build.xml (working copy) @@ -39,10 +39,10 @@ <!-- jnidispatch library release version --> <property name="jni.major" value="3"/> <property name="jni.minor" value="0"/> - <property name="jni.revision" value="6"/> + <property name="jni.revision" value="7"/> <property name="jni.build" value="${build.number}"/> <property name="jni.version" value="${jni.major}.${jni.minor}.$ {jni.revision}"/> - <property name="jni.md5" value="892beacd437514d23ed9b1cefeb2ead6"/> + <property name="jni.md5" value="8b5a20e7d71a719158113bb2ad97650e"/> <property name="spec.title" value="Java Native Access (JNA)"/> <property name="spec.vendor" value="${vendor}"/> <property name="spec.version" value="${jna.major}"/>








.patch