Skip to content

Commit 506a03b

Browse files
committed
Add functional description, fixes #519
1 parent 3ffae4b commit 506a03b

File tree

3 files changed

+68
-1
lines changed

3 files changed

+68
-1
lines changed

CHANGES.md

+1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ Features
1111
* [#510](https://github.com/java-native-access/jna/pull/510): Added `GetCommState`, `GetCommTimeouts` `SetCommState` and `SetCommTimeouts` to `com.sun.jna.platform.win32.Kernel32`. Added `DCB` structure to `com.sun.jna.platform.win32.WinBase` - [@MBollig](https://github.com/MBollig).
1212
* [#512](https://github.com/java-native-access/jna/pull/512): Make loading debug flags mutable [@lwahonen](https://github.com/lwahonen).
1313
* [#514](https://github.com/java-native-access/jna/pull/514): Added `host_processor_info` to `com.sun.jna.platform.mac.SystemB` - [@dbwiddis](https://github.com/dbwiddis).
14+
* [#519](https://github.com/java-native-access/jna/pull/519): Added JNA functional overview - [@twall](https://github.com/twall).
1415

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

README.md

+2-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ JNA provides Java programs easy access to native shared libraries without writin
1111

1212
JNA allows you to call directly into native functions using natural Java method invocation. The Java call looks just like the call does in native code. Most calls require no special handling or configuration; no boilerplate or generated code is required.
1313

14-
JNA uses a small JNI library stub to dynamically invoke native code. The developer uses a Java interface to describe functions and structures in the target native library. This makes it quite easy to take advantage of native platform features without incurring the high overhead of configuring and building JNI code for multiple platforms.
14+
JNA uses a small JNI library stub to dynamically invoke native code. The developer uses a Java interface to describe functions and structures in the target native library. This makes it quite easy to take advantage of native platform features without incurring the high overhead of configuring and building JNI code for multiple platforms. Read this [more in-depth description](https://github.com/java-native-access/jna/blob/master/www/FunctionalDescription.md).
1515

1616
While significant attention has been paid to performance, correctness and ease of use take priority.
1717

@@ -112,6 +112,7 @@ Using the Library
112112
=================
113113

114114
* [Getting Started](https://github.com/java-native-access/jna/blob/master/www/GettingStarted.md)
115+
* [Functional Description](https://github.com/java-native-access/jna/blob/master/www/FunctionalDescription.md).
115116
* [Mapping between Java and Native](https://github.com/java-native-access/jna/blob/master/www/Mappings.md)
116117
* [Using Pointers and Arrays](https://github.com/java-native-access/jna/blob/master/www/PointersAndArrays.md)
117118
* [Using Structures and Unions](https://github.com/java-native-access/jna/blob/master/www/StructuresAndUnions.md)

www/FunctionalDescription.md

+65
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
Functional Overview
2+
===================
3+
4+
JNA's platform-specific functionality is provided by the [libffi
5+
library](https://github.com/atgreen/libffi). Previous to the integration of
6+
libffi into JNA (largely performed by wmeissner), hand-coded assembly was used
7+
to support linux, sparc, windows, and Mac OSX (intel and PPC targets). The
8+
libffi library provides an abstraction for calling arbitrary target addresses
9+
with an arbitrary set of typed arguments.
10+
11+
The `ffi_prep_cif()` call describes how the target function wishes to be
12+
called, while `ffi_call()` actually performs the call, provided the CIF
13+
structure returned by `ffi_prep_cif()`, an arguments array, and a buffer for a
14+
return value.
15+
16+
17+
Interface Mapping
18+
-----------------
19+
When you instantiate a native library interface via `Native.loadLibrary()`,
20+
JNA creates a proxy which routes all method invocations through a single
21+
`invoke` function in `Library.Handler`. This method looks up an appropriate
22+
`Function` object which represents a function exported by the native library.
23+
The proxy handler may perform some initial name translation to derive the
24+
actual native library function name from the invoked proxy function.
25+
26+
Once the `Function` object is found, its generic `invoke` method is called
27+
with all available arguments. The proxy function signature is used to figure
28+
out the types of the incoming arguments and the desired return type.
29+
30+
The `Function` object performs any necessary conversion of arguments,
31+
converting `NativeMapped` types into their native representation, or applying
32+
a `TypeMapper` to any incoming types which have registered for `TypeMapper`
33+
conversion. Similar conversion is performed on function return. By default,
34+
all `Structure` objects have their Java fields copied into their native memory
35+
before the native function call, and copied back out after the call.
36+
37+
All `Function` invocations are routed through different native methods based
38+
on their return type, but all those native methods are dispatched through the
39+
same `dispatch` call in `native/dispatch.c`. That function performs any final
40+
conversions of Java objects into native representations before building a
41+
function call description for use by libffi.
42+
43+
The libffi library requires a description of the target function's arguments
44+
and return type in order to perform a platform-specific construction of the
45+
stack suitable for the final native call invocation. Once libffi has
46+
performed the native call (via `ffi_call()`), it copies the result into a
47+
buffer provided by JNA, which then converts it back into an appropriate Java
48+
object.
49+
50+
Direct Mapping
51+
--------------
52+
JNI provides for registering a native function to be called directly when a
53+
method marked `native` is called from Java. JNA constructs code stubs with
54+
libffi for each native method registered via the `Native.register()` call (JNA
55+
uses reflection to identify all methods with the `native` qualifier in the
56+
direct-mapped class). Each stub dispatches to the function `dispatch_direct`
57+
in `native/dispatch.c`, and has an associated structure allocated which fully
58+
describes the function invocation to avoid any reflection costs at runtime.
59+
60+
The central `dispatch_direct` function attempts to pass the Java call stack
61+
as-is to the native function (again, using `ffi_call()` from libffi).
62+
The more non-primitive arguments are used, the more the direct dispatch has to
63+
do extra work to convert Java objects into native representations on the
64+
stack. Ideal performance is achieved by using only primitive or `Pointer`
65+
arguments.

0 commit comments

Comments
 (0)