163. Introducing Jextract
Jextract (https://github.com/openjdk/jextract) is a very handy tool capable to consume the headers of native libraries (*.h files) and producing low-level Java native bindings. Via this tool, we can save a lot of time since we can focus only on calling native code without carrying about the mechanical steps of loading libraries, writing method handle, downcall, and upcall stubs.Jextract is a command line tool that can be downloaded from https://jdk.java.net/jextract. The main options of this tool are listed here:–source When we write jextract –source, we instruct Jextract to generate from the given header file the corresponding source files without classes. When this option is omitted, Jextract will generate classes.– output path By default, the generated files are placed in the current folder. Via this option, we can point out the path where these files should be placed.-t <package> By default, Jextract uses the unnamed package name. Via this option, we can specify the package name for the generated classes.-I <dir> Specify one or more paths that should be appended to the existing search paths. The given order is respected at search. –dump-includes <String> This option allows you to filter the symbols. First, use this option to extract all symbols in a file. Next, edit the file to keep only the needed symbols. Finally, pass this file to Jextract.The complete list of options is available at https://github.com/openjdk/jextract.
164. Generating native binding for modf()
In Problem 160, we have located, prepared, and called the modf() foreign function via the Foreign Linker API. Now, let’s use Jextract to generate the native binding needed to call modf().For Windows, the modf() foreign function is described in the math.h header file. If you have installed MinGW (https://sourceforge.net/projects/mingw-w64/) for 64-bit then this header file is available in the mingw64\x86_64-w64-mingw32\include folder. If we want to generate the native bindings for math.h, we can do it as follows:

Figure 7.25 – Generating the native bindings from math.h
Or, as plain text:
C:\SBPBP\GitHub\Java-Coding-Problems-Second-Edition\Chapter07\P164_JextractAndModf> jextract –source –output src\main\java -t c.lib.math -I C:\MinGW64\mingw64\x86_64-w64-mingw32\include C:\MinGW64\mingw64\x86_64-w64-mingw32\include\math.h
So, we generated the source files (–sources), in the src\main\java subfolder of the current project (–output), in the package c.lib.math (-t). The math.h is loaded from mingw64\x86_64-w64-mingw32\include.After running this command you’ll find in c.lib.math the native bindings for all the symbols found in math.h. Most probably, this is not what we want, since we call only the modf() foreign function. Filtering symbols is a two-step process. First, we generate a dump of all symbols as follows:

Figure 7.26 – Creating a dump file containing all symbols from math.h
Or, as plain text:
C:\SBPBP\GitHub\Java-Coding-Problems-Second-Edition\Chapter07\P164_JextractAndModf>jextract –dump-includes includes.txt -I C:\MinGW64\mingw64\x86_64-w64-mingw32\include C:\MinGW64\mingw64\x86_64-w64-mingw32\include\math.h
This command will write in the project root a file named includes.txt containing all symbols found in math.h. The second step consists of editing this file. For instance, we have kept only the symbol for modf() as follows:

Figure 7.27 – Editing the includes.txt to keep only the needed symbols
Next, we pass the edited includes.txt to Jextract as follows:

Figure 7.28 – Run Jextract with the filtered includes.txt
Or, as plain text:
C:\SBPBP\GitHub\Java-Coding-Problems-Second-Edition\Chapter07\P164_JextractAndModf>jextract –source @includes.txt –output src\main\java -t c.lib.math -I C:\MinGW64\mingw64\x86_64-w64-mingw32\include C:\MinGW64\mingw64\x86_64-w64-mingw32\include\math.h
This time, in c.lib.math you’ll find the native bindings only for modf() foreign function. Take your time to inspect each of these files and see how they interact at the code level. Since we generate only the sources, we have to compile the project to obtain the classes. If you prefer to generate the classes directly via Jextract then you can use a command as follows (now, the sources will not be generated, only the classes):

Figure 7.29 – Generating the classes of native bindings
Or, as plain text:
C:\SBPBP\GitHub\Java-Coding-Problems-Second-Edition\Chapter07\P164_JextractAndModf>jextract @includes.txt –output target\classes -t c.lib.math -I C:\MinGW64\mingw64\x86_64-w64-mingw32\include C:\MinGW64\mingw64\x86_64-w64-mingw32\include\math.h
Next, we can use the generated bindings in a Java application to call the modf() function. The code is straightforward (we don’t need to write the method handle and there is no need to explicitly use invoke()/invokeExact()):
double x = 89.76655;
try (Arena arena = Arena.openConfined()) {
MemorySegment segmentIntptr
= arena.allocate(ValueLayout.JAVA_DOUBLE);
double fractional = modf(x, segmentIntptr);
System.out.println(“Fractional part: ” + fractional
+ ” Integer part: ” + segmentIntptr.get(
ValueLayout.JAVA_DOUBLE, 0));
}
The modf() function is imported from c.lib.math.math_h package.
Summary
This chapter covered 28 problems. Most of them were focused on the new Foreign (Function) Memory APIs, or Project Panama. As you saw, this API is much more intuitive and powerful than the classical approaches of using JNI, JNA, and JNR. Moreover, the Jextract tool is very handy to generate native binding from the headers of native shared libraries and saves us from a lot of mechanical work.