You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: java-does-usb/jextract/README.md
+19-19Lines changed: 19 additions & 19 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -2,7 +2,7 @@
2
2
3
3
Some of the binding code for accessing native functions and data structures is generated with [jextract](https://jdk.java.net/jextract/). The tool is still under construction and has its limitations.
4
4
5
-
In order to generate the code, the scripts in this directory have to be run (`gen_linux.sh`, `gen_macos.sh` and `gen_win_xxx.cmd`). Each script has to be run on that particular operating system.
5
+
In order to generate the code, the scripts in the subdirectories have to be run (`linux/gen_linux.sh`, `macos/gen_macos.sh` and `/windowsgen_win.cmd`). Each script has to be run on the particular operating system.
6
6
7
7
The code is generated in directories below `gen`, i.e. `main/java/net/codecrete/usb/linux/gen` and similar for the other operating systems. For each library (`xxx.so` or `xxx.dll`) and each macOS framework, a separate package is created.
8
8
@@ -13,11 +13,11 @@ The resulting code is then committed to the source code repository. Before the c
13
13
14
14
## General limitations
15
15
16
-
- The binaries for *jextract* on https://jdk.java.net/jextract/ have not been updated for JDK 20. So it must be built from source. Instructions can be found at [Building & Testing](https://github.com/openjdk/jextract#building--testing).
16
+
- The binaries for *jextract* on https://jdk.java.net/jextract/ have not been updated for JDK 21. So it must be built from source. Instructions can be found at [Building & Testing](https://github.com/openjdk/jextract#building--testing).
17
17
18
-
- According to the jextract mailing list, it would be required to create separate code form Intel x64 and ARM64 architecture. And jextract would need to be run on each architecture separately (no cross-compilation). Fortunately, this doesn't seem to be the case. Linux code generated on Intel x64 also runs on ARM64 without change. The same holds for macOS. However, jextract needs to be run on each operating system separately.
18
+
- According to the jextract mailing list, it would be required to create separate code for Intel x64 and ARM64 architecture. And jextract would need to be run on each architecture separately (no cross-compilation). Fortunately, this doesn't seem to be the case. Linux code generated on Intel x64 also runs on ARM64 without change. The same holds for macOS. However, jextract needs to be run on each operating system separately.
19
19
20
-
- JDK 20 introduced a new feature for saving the thread-specific error values (`GetLastError()` on Windows, `errno` on Linux). To use it, an additional parameter must be added to function calls. Unfortunately, this is not yet supported by jextract. So with the JDK 20 updates, more code is written manually and less is generated by jextract.
20
+
- JDK 20 introduced a new feature for saving the thread-specific error values (`GetLastError()` on Windows, `errno` on Linux). To use it, an additional parameter must be added to function calls. Unfortunately, this is not yet supported by jextract. So a good number of function bindings have to be written manually.
21
21
22
22
-`typedef` and `struct`:
23
23
@@ -30,8 +30,8 @@ The resulting code is then committed to the source code repository. Before the c
30
30
-*jextract* is not really transparent about what it does. It often skips elements without providing any information. In particular, it will silently skip a requested element in these cases:
31
31
32
32
-`--include-var myvar` if `myvar` is declared as `static`.
33
-
-`--include-var myvar` if `myvar` is an `enum` constant. `enum` constants must be requested with `--include-macro`.
34
-
-`--include-macro MYMACRO` if `MYMACRO` is function-like, even if it evaluates to a constant.
33
+
-`--include-var myvar` if `myvar` is an `enum` constant. `enum` constants must be requested with `--include-constant`.
34
+
-`--include-constant MYCONSTANT` if `MYCONSTANT` is function-like, even if it evaluates to a constant.
35
35
-`--include-struct mystruct` if `mystruct` is actually a `typedef` to a `struct`.
36
36
-`--include-typedef mystruct` if `mystruct` is actually a `struct`.
37
37
-`--include-typedef mytypedef` if `mytypedef` is a `typedef` for a primitive type.
@@ -40,7 +40,7 @@ The resulting code is then committed to the source code repository. Before the c
40
40
41
41
## Linux
42
42
43
-
To run the script, most likely the header files for *libudev* must be installed (the library itself is most likely already installed):
43
+
To run the script, the header files for *libudev* must be present. In most cases, they aren't install by default (in contrast to the library itself):
@@ -81,11 +81,9 @@ Compared to Linux and macOS, the code generation on Windows is very slow (about
81
81
82
82
The known limitations are:
83
83
84
-
- Variable size `struct`: Several Windows struct are of variable size. The last member is an array. The `struct` definition specifies array length 1. But you are expected to allocate more space depending on the actual array size you need. *jextract* generates code for array length 1 and when access array members, the length is checked. So the generated code is difficult to use. Variable size `struct`s are a pain - in any language.
84
+
- Variable size `struct`: Several Windows struct are of variable size. The last member is an array. The `struct` definition specifies array length 1. But you are expected to allocate more space depending on the actual array size you need. *jextract* generates code for array length 1 and checks the length when the members are accessed. So the generated code is difficult to use. Variable size `struct`s are a pain - in any language.
85
85
86
-
-`USB_NODE_CONNECTION_INFORMATION_EX`: This struct uses a packed layout without considering alignment. The last four members are on an odd offset even though they are multiple bytes long. *jextract* creates the correct offsets but defines strict alignment constraints for the members. So the memory layout cannot be instantiated as it throws an exception.
87
-
88
-
- GUID constants like `GUID_DEVINTERFACE_USB_DEVICE` do not work. While code is generated, the code fails at run-time as it is unable to locate the symbol. This is due to the fact that `GUID_DEVINTERFACE_USB_DEVICE` actually resolve to a variable definition and not to a variable declaration. It is not part of any library. Such constants should be skipped by *jextract*.
86
+
- GUID constants like `GUID_DEVINTERFACE_USB_DEVICE` do not work. While code is generated, the code fails at run-time as it is unable to locate the symbol. This is due to the fact that `GUID_DEVINTERFACE_USB_DEVICE` actually resolve to a variable definition and not to a variable declaration. The GUID constant is not contained in any library; instead the header files use linkage options to generate the constant in the callers code, which does not work with FFM. Such constants should be skipped by *jextract*.
89
87
90
88
-*jextract* is a batch script and turns off *echo mode*. If a single batch scripts has multiple calls of *jextract*, two things need to be considered:
91
89
@@ -98,16 +96,18 @@ The known limitations are:
98
96
99
97
*jextract* generates a comprehensive set of methods for each function, struct, struct member etc. Most of it will not be used as a typical application just uses a subset of struct members, might only read or write them etc. So a considerable amount of code is generated. For some types, it's a bit excessive.
100
98
101
-
The worst example is [`IOUSBInterfaceStruct100`](https://github.com/manuelbl/JavaDoesUSB/blob/main/java-does-usb/src/main/java/net/codecrete/usb/macos/gen/iokit/IOUSBDeviceStruct100.java) (macOS). This is a `struct` consisting of about 75 member functions. It's basically a vtable of a C++ class. *jextract* generates the same number of classes plus a huge class for the struct itself. The total code size (compiled) for this single `struct` is over 300 kByte.
99
+
The worst example is [`IOUSBInterfaceStruct190`](https://github.com/manuelbl/JavaDoesUSB/blob/main/java-does-usb/src/main/java/net/codecrete/usb/macos/gen/iokit/IOUSBInterfaceStruct190.java) (macOS). This is a `struct` consisting of about 50 member functions. It's basically a vtable of a C++ class. For this single `struct`, *jextract* generates codes resulting in 70 class files with a total size of 227kByte..
102
100
103
-
The table below shows statictics for version 0.2.0 of the library:
101
+
The table below shows statistics for version 0.6.0 of the library:
104
102
105
103
| Operating Systems | Manually Created | % | Generated | % | Total | % |
0 commit comments