Skip to content

Commit bd05b75

Browse files
Add Native#getNativeLibrary to get access to library wrapped by Native#load or Native#register
1 parent 4f94c57 commit bd05b75

File tree

3 files changed

+141
-0
lines changed

3 files changed

+141
-0
lines changed

CHANGES.md

+1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ Features
1111
* [#1593](https://github.com/java-native-access/jna/pull/1593): Add support for DragonFly BSD x86-64 - [@liweitianux](https://github.com/liweitianux).
1212
* [#1595](https://github.com/java-native-access/jna/pull/1595): Add `IsProcessorFeaturePresent` to `c.s.j.p.win32.Kernel32` - [@dbwiddis](https://github.com/dbwiddis).
1313
* [#1602](https://github.com/java-native-access/jna/pull/1602): Add `XMoveWindow`, `XResizeWindow`, `XMoveResizeWindow`, `XRaiseWindow`, `XLowerWindow` X11 calls to `c.s.j.p.unix.X11` - [@vinceh121](https://github.com/vinceh121).
14+
* [#1613](https://github.com/java-native-access/jna/issues/1613): Added static helper method `Native#getNativeLibrary' for getting the underlying NativeLibrary instance from a Library interface instance or from a "registered" class - [@matthiasblaesing](https://github.com/matthiasblaesing).
1415

1516
Bug Fixes
1617
---------

src/com/sun/jna/Native.java

+46
Original file line numberDiff line numberDiff line change
@@ -1918,6 +1918,52 @@ public static void register(Class<?> cls, NativeLibrary lib) {
19181918
}
19191919
}
19201920

1921+
/**
1922+
* Get the {@link NativeLibrary} instance that is wrapped by the given
1923+
* {@link Library} interface instance.
1924+
*
1925+
* @param library the {@link Library} interface instance, which was created
1926+
* by the {@link Native#load Native.load()} method
1927+
* @return the wrapped {@link NativeLibrary} instance
1928+
*/
1929+
public static NativeLibrary getNativeLibrary(final Library library) {
1930+
if(library == null) {
1931+
throw new IllegalArgumentException("null passed to getNativeLibrary");
1932+
}
1933+
if(! Proxy.isProxyClass(library.getClass())) {
1934+
throw new IllegalArgumentException("library object passed to getNativeLibrary in not a proxy");
1935+
}
1936+
final InvocationHandler handler = Proxy.getInvocationHandler(library);
1937+
if (!(handler instanceof Library.Handler)) {
1938+
throw new IllegalArgumentException("Object is not a properly initialized Library interface instance");
1939+
}
1940+
return ((Library.Handler) handler).getNativeLibrary();
1941+
}
1942+
1943+
/**
1944+
* Get the {@link NativeLibrary} instance to which the given "registered"
1945+
* class is bound.
1946+
*
1947+
* @param cls the "registered" class, which was previously registered via
1948+
* the {@link Native#register register()} method
1949+
* @return the {@link NativeLibrary} instance to which the "registered"
1950+
* class is bound
1951+
*/
1952+
public static NativeLibrary getNativeLibrary(final Class<?> cls) {
1953+
if(cls == null) {
1954+
throw new IllegalArgumentException("null passed to getNativeLibrary");
1955+
}
1956+
final Class<?> mappedClass = findDirectMappedClass(cls);
1957+
synchronized(registeredClasses) {
1958+
final NativeLibrary nativeLibrary = registeredLibraries.get(mappedClass);
1959+
if (nativeLibrary == null) {
1960+
throw new IllegalArgumentException("Class " + cls.getName() + " is not currently registered");
1961+
} else {
1962+
return nativeLibrary;
1963+
}
1964+
}
1965+
}
1966+
19211967
/* Take note of options used for a given library mapping, to facilitate
19221968
* looking them up later.
19231969
*/
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
/* Copyright (c) 2024 Matthias Bläsing, All Rights Reserved
2+
*
3+
* The contents of this file is dual-licensed under 2
4+
* alternative Open Source/Free licenses: LGPL 2.1 or later and
5+
* Apache License 2.0. (starting with JNA version 4.0.0).
6+
*
7+
* You can freely decide which license you want to apply to
8+
* the project.
9+
*
10+
* You may obtain a copy of the LGPL License at:
11+
*
12+
* http://www.gnu.org/licenses/licenses.html
13+
*
14+
* A copy is also included in the downloadable source code package
15+
* containing JNA, in file "LGPL2.1".
16+
*
17+
* You may obtain a copy of the Apache License at:
18+
*
19+
* http://www.apache.org/licenses/
20+
*
21+
* A copy is also included in the downloadable source code package
22+
* containing JNA, in file "AL2.0".
23+
*/
24+
package com.sun.jna;
25+
26+
import java.util.Collections;
27+
import junit.framework.TestCase;
28+
29+
/**
30+
* Check getNativeLibrary functions in Native
31+
*/
32+
public class NativeGetNativeLibraryTest extends TestCase {
33+
34+
private NativeLibrary libUTF8;
35+
private TestLib libUTF8Interface;
36+
37+
@Override
38+
protected void setUp() {
39+
libUTF8 = NativeLibrary.getInstance("testlib",
40+
Collections.singletonMap(Library.OPTION_STRING_ENCODING, "UTF-8"));
41+
Native.register(TestLibUTF8.class, libUTF8);
42+
libUTF8Interface = Native.load("testlib", TestLib.class,
43+
Collections.singletonMap(Library.OPTION_STRING_ENCODING, "UTF-8"));
44+
}
45+
46+
public void testGetNativeLibraryInterface() {
47+
NativeLibrary nl = Native.getNativeLibrary(libUTF8Interface);
48+
assertTrue(nl instanceof NativeLibrary);
49+
}
50+
51+
public void testGetNativeLibraryDirect() {
52+
NativeLibrary nl = Native.getNativeLibrary(TestLibUTF8.class);
53+
assertTrue(nl instanceof NativeLibrary);
54+
// This only makes sense for the direct case, as that directly wraps
55+
// a supplied instance
56+
assertEquals(libUTF8, nl);
57+
}
58+
59+
public void testGetNativeLibraryOnUnboundShouldFail() {
60+
try {
61+
Native.getNativeLibrary(new TestLib() {
62+
@Override
63+
public String returnStringArgument(Pointer input) {
64+
return "";
65+
}
66+
});
67+
assertTrue("Exception not thrown", false);
68+
} catch (IllegalArgumentException ex) {
69+
// This should be reached
70+
}
71+
}
72+
73+
public void testGetNativeLibraryOnNullShouldFail() {
74+
try {
75+
Native.getNativeLibrary((Class) null);
76+
assertTrue("Exception not thrown", false);
77+
} catch (IllegalArgumentException ex) {
78+
// This should be reached
79+
}
80+
}
81+
82+
public static void main(java.lang.String[] argList) {
83+
junit.textui.TestRunner.run(NativeGetNativeLibraryTest.class);
84+
}
85+
86+
private static class TestLibUTF8 implements Library {
87+
native String returnStringArgument(Pointer input);
88+
}
89+
90+
private interface TestLib extends Library {
91+
public String returnStringArgument(Pointer input);
92+
}
93+
94+
}

0 commit comments

Comments
 (0)