

![]() | 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.users[jna-users] loading dynamic libraries...| 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: | [jna-users] loading dynamic libraries in the global namespace | Actions... |
|---|---|---|
| From: | Filippo Carone (fili...@carone.org) | |
| Date: | Dec 12, 2008 2:36:42 pm | |
| List: | net.java.dev.jna.users | |
| Attachments: | ||
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